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

Firebase手机认证创建用户后stripeId无法触发useEffect问题解决

问题:Firebase手机认证后StripeId无法触发useEffect钩子

在使用Google Firebase手机认证创建客户账号流程中,需为用户分配StripeId,完成后重定向至信用卡信息填写页面,但目前StripeId更新后无法触发页面中的useEffect钩子,导致后续获取Setup Intent的逻辑不执行。

现有代码

页面组件代码

const { authUser, loading } = useAuthUserContext();

const {
        email = '',
        displayName = '',
        stripeId = ''
    } = authUser || {};


useEffect(() => {
        if (authUser) {
            const {
                stripeId = ''
            } = authUser;

            if (stripeId) {
                fetch('/api/setup_intent', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ customerId: stripeId })
                })
                    .then((res) => res.json())
                    .then((data) => setClientSecret(data.clientSecret));
            }
        }
    }, [authUser, loading, stripeId]);

Auth Context钩子代码

const [authUser, setAuthUser] = useState<IUser | null>(null);

const authStateChanged = async (authState: any) => {
        if (!authState) {
            setLoading(false);
            return;
        }

        setLoading(true);

        const formattedUser = formatAuthUser(authState);

        setAuthUser(formattedUser);

        const { uid } = authState;

        const docRef = doc(firestore, 'users', uid);
        const snap = await getDoc(docRef);

        if (snap.exists()) {
            setAuthUser((f: any) => ({ ...f, ...snap.data() }));
        }

        setLoading(false);
    };

问题原因

当前代码使用getDoc仅一次性获取Firestore中的用户数据,而StripeId通常是在用户认证完成后,通过异步逻辑(比如创建Stripe客户后写入Firestore)添加到用户文档中的。此时getDoc已经执行完毕,无法感知后续StripeId的写入操作,导致authUser状态未更新,进而无法触发依赖authUser或stripeId的useEffect钩子。

修复方案

将一次性获取的getDoc替换为onSnapshot实时监听Firestore文档变化,这样当StripeId写入用户文档后,会自动触发快照更新,进而更新authUser状态,触发useEffect执行后续逻辑:

const [authUser, setAuthUser] = useState<IUser | null>(null);

const authStateChanged = async (authState: any) => {
        if (!authState) {
            setLoading(false);
            return;
        }

        setLoading(true);

        const formattedUser = formatAuthUser(authState);

        setAuthUser(formattedUser);

        const { uid } = authState;

        const docRef = doc(firestore, 'users', uid);
        // 替换getDoc为onSnapshot实时监听文档变化
        onSnapshot(docRef, (doc) => {
            if (doc.exists()) {
                setAuthUser((f: any) => ({ ...f, ...doc.data() }));
            }
            setLoading(false);
        });
    };

额外说明:

  • onSnapshot会在文档首次获取和每次更新时触发,确保authUser能及时同步最新数据
  • useEffect的依赖数组中,stripeId是从authUser解构而来,可仅保留authUser和loading作为依赖,避免冗余

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:15:25