Flutter中如何在默认Firebase应用与次级Firebase应用之间共享身份认证
这个问题的核心原因很明确:你的次级FirebaseApp虽然配置了Firestore,但没有关联对应的FirebaseAuth实例,也没有同步用户的认证状态到这个次级App。Firebase的每个App实例都是独立的,默认App的Auth认证状态不会自动传递给次级App,所以当次级Firestore请求数据时,request.auth会是null,自然被规则拦截了。
下面是具体的解决步骤和代码实现:
1. 为次级FirebaseApp添加对应的FirebaseAuth实例
首先修改你的依赖注入模块,给次级App创建专属的FirebaseAuth实例,而不是复用默认的:
@module abstract class RegisterModule { @preResolve Future<FirebaseApp> get firebaseApp => Firebase.initializeApp(); @singleton FirebaseAuth firebaseAuth() => FirebaseAuth.instance; @Named("secondary") @preResolve Future<FirebaseApp> get adminFirebaseApp => Firebase.initializeApp( name: 'admin', options: const FirebaseOptions( appId: 'app-id', apiKey: 'api-key', messagingSenderId: 'messaging-sender-id', projectId: 'project-id', ), ); // 添加次级Auth实例 @Named("secondary") @singleton FirebaseAuth adminFirebaseAuth( @Named("secondary") FirebaseApp firebaseApp) => FirebaseAuth.instanceFor(app: firebaseApp); @Named("secondary") @singleton FirebaseFirestore adminFirestore( @Named("secondary") FirebaseApp firebaseApp) => FirebaseFirestore.instanceFor(app: firebaseApp); }
2. 同步默认App的认证状态到次级App
当用户已经通过默认App完成登录后,你需要把这个认证状态同步到次级App,这样次级Firestore的请求才会带上有效的request.auth信息。最直接的方式是使用默认用户的ID Token,在次级App中进行自定义令牌登录:
// 假设你已经通过依赖注入获取到次级App和次级Auth实例 final FirebaseApp secondaryApp = getIt<FirebaseApp>(instanceName: "secondary"); final FirebaseAuth secondaryAuth = FirebaseAuth.instanceFor(app: secondaryApp); // 获取默认App的当前登录用户 final defaultUser = FirebaseAuth.instance.currentUser; if (defaultUser != null) { try { // 获取用户的ID Token(有效期1小时,需要定期刷新) final idToken = await defaultUser.getIdToken(); // 用ID Token在次级App中完成认证 await secondaryAuth.signInWithCustomToken(idToken); // 现在次级Firestore的请求就会带上认证状态了 } catch (e) { print("同步次级App认证失败: $e"); } }
3. 处理认证状态的同步与清理
- 要注意ID Token的有效期是1小时,你需要监听默认用户的认证状态变化,或者定期刷新Token并重新同步到次级App。
- 当用户从默认App登出时,记得也要同步登出次级App:
// 默认App登出 await FirebaseAuth.instance.signOut(); // 次级App同步登出 await secondaryAuth.signOut();
额外注意事项
- 确保你的次级Firebase项目在控制台的Auth -> 登录方法中启用了「自定义令牌」登录方式,否则
signInWithCustomToken会失败。 - 如果两个Firebase项目属于同一组织,也可以考虑使用Firebase Auth的跨项目认证功能,但上面的方法是最通用的,无需额外配置。
这样处理后,次级Firestore的请求就会携带有效的用户认证信息,符合你设置的request.auth != null规则要求了。
内容的提问来源于stack exchange,提问作者Kshitij Dhakal




