You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularFire .set()在Twitter登录后无限等待无响应,求解决方法

问题:Twitter登录后Firestore写入卡住无法进入then/catch

我正在使用Angular结合AngularFire开发首个应用,通过Twitter登录后,尝试在Firestore的users集合中添加用户文档。processLoggedUser函数中的Firestore写入代码永远无法进入.then()或.catch(),一直处于等待状态,但将这段代码放在构造函数或其他位置时,却能正常在Firestore中创建文档。

完整的processLoggedUser函数

processLoggedUser(): Promise<number> {
    return this.afAuth.getRedirectResult().then(async result => {
        if (result.user) {
            const uid = result.user.uid;
            const credential = result.credential as firebase.default.auth.OAuthCredential;
            console.log('Twitter answer of AuthLogin: ', result)
            this.uid = uid
            let code = 0 // 0 = default code -> error
            if (result.additionalUserInfo.isNewUser) {
                console.log("New user")
                this.user = {
                    uid: this.uid,
                    email: result.user.email,
                    displayName: result.user.displayName,
                    photoURL: result.user.photoURL.replace('_normal', ''),
                    miniPhotoURL: result.user.photoURL,
                    accessToken: credential.accessToken,
                    secret: credential.secret,
                    twitterId: result.additionalUserInfo.profile["id"],
                    username: result.additionalUserInfo.username,
                    bio: result.additionalUserInfo.profile["description"],
                    verified: result.additionalUserInfo.profile["verified"],
                    wallet: 0,
                    staff: false,
                    banned: false,
                    hidden: false
                };
                console.log(this.user)
                await this.afs.collection('users').doc(this.uid).set(this.user || {nome: "oops"}).then(res => {
                    console.log("User created", res)
                    code = 2 // Number code for new user
                }).catch(err => {
                    console.log("Error creating user", err)
                    code = 0 // Number code for error
                })
                return 2
            } else {
                await this.getUser(uid).then(res => res.subscribe(res => {
                    if (res == undefined) {
                        this.signOut()
                        code = 4 // Number code for user not found
                    } else {
                        this.user = res
                        console.log("Existing user", this.user)
                        code = 1 // Number code for existing user
                    }
                }))
            }
            return code
        }else {
            return 3
        }
    }).catch((error) => {
        console.warn(error)
        return 0 // Number code for error
    })
}

困扰的代码片段

await this.afs.collection('users').doc(this.uid).set(this.user).then(res => {
    console.log("User created", res)
    code = 2 // Number code for new user
}).catch(err => {
    console.log("Error creating user", err)
    code = 0 // Number code for error
})

问题分析与解决方法

核心问题

  1. 混合使用async/await与.then()/.catch():await本身会等待Promise完成,但链式调用.then()/.catch()会导致Promise嵌套,破坏await的等待逻辑,进而出现卡住的情况。
  2. 提前返回结果:新用户分支中,在await之后直接return 2,完全忽略Firestore操作的实际结果,内部修改code变量的逻辑根本不会影响返回值。
  3. Observable未转Promise:现有用户分支中,getUser返回的是Observable,await对Observable无效,导致代码不会等待数据获取完成就返回初始值code=0。

修正后的代码实现

1. 新用户分支修正(统一用async/await + try/catch)

if (result.additionalUserInfo.isNewUser) {
    console.log("New user")
    this.user = {
        uid: this.uid,
        email: result.user.email,
        displayName: result.user.displayName,
        photoURL: result.user.photoURL.replace('_normal', ''),
        miniPhotoURL: result.user.photoURL,
        accessToken: credential.accessToken,
        secret: credential.secret,
        twitterId: result.additionalUserInfo.profile["id"],
        username: result.additionalUserInfo.username,
        bio: result.additionalUserInfo.profile["description"],
        verified: result.additionalUserInfo.profile["verified"],
        wallet: 0,
        staff: false,
        banned: false,
        hidden: false
    };
    console.log(this.user);
    try {
        // 直接await Firestore的set操作,无需链式调用then/catch
        await this.afs.collection('users').doc(this.uid).set(this.user);
        console.log("User created");
        return 2; // 新用户创建成功
    } catch (err) {
        console.log("Error creating user", err);
        return 0; // 创建失败
    }
}

2. 现有用户分支修正(Observable转Promise)

首先需要导入firstValueFrom(RxJS 7+版本):

import { firstValueFrom } from 'rxjs';

然后修改分支代码:

else {
    try {
        // 将Observable转换为Promise,用await等待结果
        const userData = await firstValueFrom(this.getUser(uid));
        if (!userData) {
            this.signOut();
            return 4; // 用户未找到
        } else {
            this.user = userData;
            console.log("Existing user", this.user);
            return 1; // 已有用户
        }
    } catch (err) {
        console.log("Error fetching user", err);
        return 0; // 获取用户失败
    }
}

3. 整体函数优化(统一async/await语法)

把最外层的.then()也改成async/await,进一步简化逻辑:

async processLoggedUser(): Promise<number> {
    try {
        const result = await this.afAuth.getRedirectResult();
        if (result.user) {
            const uid = result.user.uid;
            const credential = result.credential as firebase.default.auth.OAuthCredential;
            console.log('Twitter answer of AuthLogin: ', result);
            this.uid = uid;

            if (result.additionalUserInfo.isNewUser) {
                this.user = { /* 保持原用户数据结构 */ };
                try {
                    await this.afs.collection('users').doc(this.uid).set(this.user);
                    console.log("User created");
                    return 2;
                } catch (err) {
                    console.log("Error creating user", err);
                    return 0;
                }
            } else {
                try {
                    const userData = await firstValueFrom(this.getUser(uid));
                    if (!userData) {
                        this.signOut();
                        return 4;
                    } else {
                        this.user = userData;
                        console.log("Existing user", this.user);
                        return 1;
                    }
                } catch (err) {
                    console.log("Error fetching user", err);
                    return 0;
                }
            }
        } else {
            return 3; // 无登录结果
        }
    } catch (error) {
        console.warn(error);
        return 0; // 登录过程出错
    }
}

内容的提问来源于stack exchange,提问作者Felix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 18:49:11