AngularFire中FIREBASE_OPTIONS异步注入(Axios拉取配置)的实现问题
问题根因
直接在FIREBASE_OPTIONS的工厂函数里返回Promise无法生效,核心是Angular的依赖注入系统默认只同步解析工厂返回的实际值,不会自动识别并等待Promise resolve,直接返回的Promise会被当成配置对象本身传给AngularFire,自然无法完成初始化。
推荐实现方案
用到Angular内置的APP_INITIALIZER令牌实现启动前的异步阻塞逻辑,等配置拉取完成后再正式初始化应用,具体步骤:
- 先创建一个临时的配置缓存容器,用于存储异步拉取到的Firebase配置
// src/app/utils/firebase-config-cache.ts export const firebaseConfigCache = { config: null as { apiKey: string, authDomain: string, projectId: string, storageBucket: string, messagingSenderId: string, appId: string, measurementId: string } | null }; - 在应用根模块的providers数组中配置两类提供器:
- 第一类配置
APP_INITIALIZER,发起Axios请求拉取配置,拉取完成后写入缓存 - 第二类配置
FIREBASE_OPTIONS,直接从缓存中读取已经拉取完成的配置
providers: [ // 应用启动前的阻塞任务配置 { provide: APP_INITIALIZER, useFactory: () => { // 直接返回执行拉取逻辑的函数,函数返回Promise return () => { return axios.get('/api/your-firebase-config-endpoint') .then(response => { // 拉取成功后把配置写入缓存 firebaseConfigCache.config = response.data; }); }; }, // 如果你的Axios是通过依赖注入配置过自定义实例的,把对应的注入标识加到deps数组里即可 deps: [], // 这个配置必须加,APP_INITIALIZER支持多实例注入,缺了会覆盖Angular内置的启动逻辑 multi: true }, // Firebase配置提供器 { provide: FIREBASE_OPTIONS, useFactory: () => { // 因为APP_INITIALIZER会等拉取完成才执行后续初始化,这里读取的时候缓存一定已有值 return firebaseConfigCache.config; } } ] - 第一类配置
常见踩坑提醒
- 不要尝试给
FIREBASE_OPTIONS的工厂函数加async修饰直接返回Promise,DI系统不会自动解析异步返回值,依然会把Promise对象作为配置传入,导致AngularFire报初始化参数无效的错误 APP_INITIALIZER的multi: true配置不能漏,否则会替换掉Angular内置的其他启动初始化逻辑,导致应用路由、状态管理等模块初始化异常- 如果不想用全局缓存变量,也可以把缓存逻辑封装成可注入的
AppConfigService,在服务内部存储拉取到的配置,APP_INITIALIZER中注入该服务触发拉取,FIREBASE_OPTIONS的工厂中同样注入该服务读取配置即可,逻辑完全一致。
内容的提问来源于stack exchange,提问作者G .E
相关产品推荐
相关产品推荐

