监控 Firebase 身份验证对象属性更改?

Posted

技术标签:

【中文标题】监控 Firebase 身份验证对象属性更改?【英文标题】:Monitor Firebase Auth Object property changes? 【发布时间】:2019-12-13 01:41:10 【问题描述】:

我已经使用 Firebase Auth 和 Firestore 通过自己的电子邮件验证流程来实施,因为我需要使用自定义电子邮件模板。客户端,UI 是用 React 完成的。

流程如下:

1) 用户注册,我打电话给firebase.auth().createUserWithEmailAndPassword()

2) My Cloud Function 监听使用functions.auth.user().onCreate() 创建新用户的时间。它使用其 UID 作为文档 ID 在 Firestore 中生成一条记录,并设置令牌和创建时间。

3) 用户单击电子邮件中的激活链接,加载 UI 视图,该视图调用验证令牌的云函数。验证后,它会为用户更新 auth 对象:

admin.auth().updateUser(uid, 
   emailVerified: true
);

4) 在我调用函数的 UI 中,我等待响应,然后将它们发送到他们可以选择计划的页面

    async function actionCode() 
        try 
            await firebase.functions().httpsCallable('verifyToken')(
                token: match.params.token
            );
            history.push('/select-plan');
         catch (e) 
            setAlert(
                message: "Error",
                description: e.message,
                type: "error"
            );
            setLoading(false);
        
    

我遇到的问题是在我的应用程序中,我根据firebase.auth().currentUser 对象进行路由。例如(删除了一些代码..)

function App() 
    const [loggedIn, setLoggedIn] = useState(false);
    const [user, setUser] = useState(null);

    useEffect(() => 
        if(firebase.auth().currentUser) setLoggedIn(true);

        return firebase.auth().onAuthStateChanged(function(user) 
            if (user) 
                setUser(user);
                setLoggedIn(true);
                setLoading(false);
             else 
                setLoggedIn(false);
                setUser(null);
                setLoading(false);
            
        );
    );

    if(loading) return <div></div>

    if(!loggedIn) 
        return authWrapper(
            <Switch>
                <Route path="/login" component=Login />
                <Route path="/register" component=Register />
                <Redirect to="/login" />
            </Switch>
        );
    

    if(!user.emailVerified) 
        return authWrapper(
            <Switch>
                <Route path="/register-success" component=RegisterSuccess />
                <Route path="/activate-account/:token" component=ActivateAccount />
                <Redirect to="/register-success" />
            </Switch>
        );
    

    return authWrapper(
        <div>
            Logged In etc
        </div>
    );

我遇到的问题是,当你更改 auth 对象时,它并没有反映在 currentUser 对象中,onAuthStateChanged 函数也没有更新的属性。仅当您重新加载整个应用时才会发生这种情况。

有没有人知道我可以在这里取得进展的方法。由于 currentUser 对象没有更新,我的路由中断,用户在重新加载应用程序之前无法继续前进。

【问题讨论】:

【参考方案1】:

将电子邮件地址设置为已验证是纯服务器端操作。它不会自动通知客户端用户配置文件已更新。因此,客户端只有在刷新其令牌时才会获取更改,无论是在您重新启动应用程序时,还是在令牌自动刷新时(每小时发生一次)。

如果您想尽快获取更新的属性,可以通过调用User.reload() 强制刷新令牌。有几种常见的方法可以做到这一点:

    在您等待验证电子邮件地址时,定期在您的应用中调用它。 在您的应用中有一个按钮,用户单击该按钮可刷新令牌,例如我验证了我的电子邮件地址。 当应用返回前台时,通常用户会通过另一个应用中的操作来验证电子邮件地址。 通过在验证电子邮件地址后从您的服务器向应用程序发送通知。您可以为此使用 FCM 数据消息,或任何其他客户端到服务器的推送机制。

【讨论】:

谢谢弗兰克。这对我有用,一旦我的 verifyToken 函数返回,我就可以简单地调用它。

以上是关于监控 Firebase 身份验证对象属性更改?的主要内容,如果未能解决你的问题,请参考以下文章

无法读取未定义的属性“电子邮件”; firebase 身份验证();使用 Vuex

NuxtJS 状态更改和 firebase 身份验证

无法使用 Ngrx 读取未定义的属性“firebaseApp”

可以在 Firebase 3 中实现自定义身份验证属性并将其与安全安全规则一起使用吗?

Firebase Auth UI 如何处理重新身份验证?

如何在 vue 上处理 Firebase 身份验证