监控 Firebase Auth 对象属性更改?

K20*_*0GH 4 firebase reactjs firebase-authentication google-cloud-functions

我已经使用 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
});
Run Code Online (Sandbox Code Playgroud)

4)在我调用该函数的用户界面中,我等待响应,然后将他们发送到一个页面,他们可以在其中选择他们的计划

    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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是在我的应用程序内,我根据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>
    );
}
Run Code Online (Sandbox Code Playgroud)

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

有谁知道我可以在这里进步的方法吗?由于 currentUser 对象不会更新,我的路由会中断,并且用户在重新加载应用程序之前无法进一步前进。

Fra*_*len 5

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

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

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