Настройка аутентификации Firebase в автономном Angular

Я использую хранилище Firebase для одного из своих проектов с автономным интерфейсом Angular 17. Я также хотел интегрировать аутентификацию Firebase. Поскольку я использую автономный angular, у меня нет ngmodules. Вот настройка firebaseapp, хранилища и getAuth в моем app.config.ts:

import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { provideStorage, getStorage } from '@angular/fire/storage';
import { provideAuth, getAuth } from '@angular/fire/auth';
//bunch of other irrelevant imports

import { environment } from 'myenvpath';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideAnimationsAsync(),
    importProvidersFrom([BrowserAnimationsModule], MatDialogModule),
    provideHttpClient(withInterceptors([authInterceptor])),
    JwtstoreService,
    {
      provide: JWT_OPTIONS,
      //jwt setup
    },
    JwtHelperService,
    provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
    provideStorage(() => getStorage()),
    provideAuth(() => getAuth()),
  ],
};

Я использую собственный токен jwt для аутентификации Firebase, который у меня есть в локальном хранилище. Я создал файл Storage.service.ts для аутентификации. У него также есть один метод получения данных из хранилища Firebase.

import { Injectable } from '@angular/core';
import { getStorage, ref, getDownloadURL } from '@angular/fire/storage';
import { getAuth, signInWithCustomToken } from '@angular/fire/auth';

@Injectable({
  providedIn: 'root',
})
export class StorageService {
  private authInitialized = false;

  constructor() {}

  private async initializeAuth(): Promise<void> {
    if (this.authInitialized) return;

    const firebaseToken = localStorage.getItem('fbtoken');
    if (!firebaseToken) {
      throw new Error('Firebase token is missing.');
    }

    const auth = getAuth();
    await signInWithCustomToken(auth, firebaseToken);
    this.authInitialized = true;
  }

  async getDownloadURL(path: string): Promise<string> {
    await this.initializeAuth();
    const storage = getStorage();
    const storageRef = ref(storage, path);
    return await getDownloadURL(storageRef);
  }
}

В своих компонентах я просто вызываю метод getDownloadURL(), если хочу получить что-то из хранилища (конечно, служба хранилища внедряется в конструктор компонента).

Когда я запускаю свое приложение и дохожу до момента, когда инициируется взаимодействие с хранилищем (вызывается метод getDownloadURL()), я получаю следующую ошибку в консоли браузера:

Error: Either AngularFireModule has not been provided in your AppModule (this can be done manually or implictly using
provideFirebaseApp) or you're calling an AngularFire method outside of an NgModule (which is not supported).

Поскольку я не получаю сообщения об отсутствии токена или других подобных ошибок, похоже, проблема в настройке app.config и/или Storage.service. В ошибке постоянно упоминается appmodule, но я снова использую автономный angular, у меня нет app.module или @ngmodules...

Я не думаю, что ошибка исходит из моего бэкэнда, поскольку я отлично получаю обратно свой собственный токен.

Некоторое время я использовал хранилище Firebase без интеграции аутентификации, и оно работало нормально.

Любая помощь приветствуется!

🤔 А знаете ли вы, что...
Angular Material - это набор готовых компонентов и стилей для создания стильных веб-приложений с использованием Angular.


69
1

Ответ:

Решено

Не понимаю почему, но это сработало:

import { Injectable, inject } from '@angular/core';
import { getStorage, ref, getDownloadURL } from '@angular/fire/storage';
import { Auth, getAuth, signInWithCustomToken } from '@angular/fire/auth';

@Injectable({
  providedIn: 'root',
})
export class StorageService {
  private authInitialized = false;
  private auth = inject(Auth); //Auth injection

  constructor() {}

  private async initializeAuth(): Promise<void> {
    if (this.authInitialized) return;

    const firebaseToken = localStorage.getItem('fbtoken');
    if (!firebaseToken) {
      throw new Error('Firebase token is missing.');
    }
    this.auth = getAuth(); //refer getAuth() to this.auth
    await signInWithCustomToken(this.auth, firebaseToken);
    this.authInitialized = true;
  }

  async getDownloadURL(path: string): Promise<string> {
    await this.initializeAuth();
    const storage = getStorage();
    const storageRef = ref(storage, path);
    return await getDownloadURL(storageRef);
  }
}

Кажется, мне нужно было ввести Auth таким образом...


Интересные вопросы для изучения

Невозможно передать значение из службы в компонентВ Angular 17 попытка очистить ввод после того, как пользователь зашел на страницу с помощью кнопки «Назад», приводит к появлению некогерентных значенийTS2305: модуль @angular/core/testing не имеет экспортированного асинхронного членаAngular 18 — фоновое изображение не отображается на мобильном устройстве, но работает в браузере и инструментах ChromeSocketio-client вызывает «Внутреннюю ошибку сервера: страница / не отображается в течение 30 секунд» в Angular 18Вход в Flutter Google не получает имя пользователя Google - FirestoreРегистрация во Flutter с использованием Firebase не работаетПеренаправление на главную страницу после входа или регистрации не работает. Firebase, частный маршрут, аутентификация по электронной почтеКак авторизовать запрос к API FCM v1 с помощью токена доступаFirebase Auth сохраняет пользователей без идентификатора с помощью OIDC