Angular Fire匿名认证写入Firebase出现多UID异常求助
问题描述
使用@angular/fire ^18.0.1操作Firebase,package.json中仅包含这一个Firebase相关依赖。
通过以下代码获取匿名认证UID,控制台仅打印一个UID:
private auth: Auth = inject(Auth); user: Observable<any> | undefined; uid!: string; async ngOnInit() { this.user = authState(this.auth); try { const userObject = await signInAnonymously(getAuth()); this.uid = userObject.user.uid; console.log(this.uid); } catch (error) { console.error("Authentication error:", error); } } async waitForUid() { while (!this.uid) { await new Promise(resolve => setTimeout(resolve, 10)); } }
执行写入Firebase操作的代码:
async ngOnInit() { await this.appComponent.waitForUid().then(() => { this.uid = this.appComponent.uid; this.loadCurrentListName(); }); } loadCurrentListName() { const listRef = ref(this.db, 'users/' + this.appComponent.uid + '/currentList/'); get(listRef).then((snapshot) => { if (snapshot.exists()) { this.currentListName.set(snapshot.val()); } else { const newPushRef = push(listRef); set(newPushRef, ''); this.currentListName.set(newPushRef.key ?? ''); } }); }
出现的异常:
- Firebase中写入了两个UID对应的数据:
{ "users": { "y7S1zoK2ccQHZlNMlAiNI2mlxHz2": { "currentList": "-O2kxqekEiDi8npAUAWj" }, "ypG9okgfYkOqjznl2Q4yionRj3M2": { "currentList": "-O2kxrE9EVM1E2RBiu05" } } }
- 切换Firefox、Chrome甚至无痕模式时,控制台打印新UID,但Firebase中总会出现固定UID
m7pX5r2aVyeNiDC1LKrjcV9VjZS2对应的数据,仅期望写入控制台打印的UID数据。
问题分析与解决方案
核心原因
1. 重复匿名登录导致多UID写入
代码中同时使用authState(this.auth)监听用户状态,又主动调用signInAnonymously(getAuth())。AngularFire的authState会自动触发匿名登录(前提是Firebase控制台已启用匿名认证),加上手动调用的登录请求,相当于发起了两次登录,生成两个不同的匿名UID,最终写入两条数据。
2. 固定UID跨场景出现的原因
这个固定UID和其他未打开的Firebase项目无关,大概率是以下情况之一:
- 代码中存在硬编码的该UID,在某个未注意的位置直接用它写入数据;
- Firebase控制台的数据库中存在该UID的测试数据,后续代码逻辑误将其当作有效数据处理;
appComponent中的uid变量初始值被设为该固定值,异步更新前就触发了写入操作。
解决步骤
步骤1:移除重复的匿名登录逻辑
保留authState监听即可,AngularFire会自动完成匿名登录,无需手动调用signInAnonymously:
private auth: Auth = inject(Auth); user: Observable<any> | undefined; uid!: string; async ngOnInit() { this.user = authState(this.auth).pipe( tap(user => { if (user) { this.uid = user.uid; console.log(this.uid); } }) ); } async waitForUid() { while (!this.uid) { await new Promise(resolve => setTimeout(resolve, 10)); } }
步骤2:排查固定UID的来源
- 全局搜索代码库中的
m7pX5r2aVyeNiDC1LKrjcV9VjZS2,确认是否存在硬编码; - 登录Firebase控制台,删除该UID对应的测试数据,观察后续是否还会生成;
- 确保
appComponent中的uid变量初始值为undefined,避免异步更新前的错误写入。
步骤3:优化数据写入的UID引用
在loadCurrentListName中直接使用当前组件的this.uid,减少对appComponent变量的依赖:
loadCurrentListName() { const listRef = ref(this.db, `users/${this.uid}/currentList/`); get(listRef).then((snapshot) => { if (snapshot.exists()) { this.currentListName.set(snapshot.val()); } else { const newPushRef = push(listRef); set(newPushRef, ''); this.currentListName.set(newPushRef.key ?? ''); } }); }
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

