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

时间:2019-08-05 13:59:58

标签: reactjs firebase firebase-authentication google-cloud-functions

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

过程如下:

1)用户注册,然后我致电 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR File "app.py", line 40, in <module> 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR standard_scaler = joblib.load('./datascaler.save') 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR File "/home/vcap/deps/0/python/lib/python2.7/site-packages/sklearn/externals/joblib/numpy_pickle.py", line 598, in load 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR obj = _unpickle(fobj, filename, mmap_mode) 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR File "/home/vcap/deps/0/python/lib/python2.7/site-packages/sklearn/externals/joblib/numpy_pickle.py", line 526, in _unpickle 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR obj = unpickler.load() 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR File "/home/vcap/deps/0/python/lib/python2.7/pickle.py", line 864, in load 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR dispatch[key](self) 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR File "/home/vcap/deps/0/python/lib/python2.7/pickle.py", line 1096, in load_global 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR klass = self.find_class(module, name) 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR File "/home/vcap/deps/0/python/lib/python2.7/pickle.py", line 1130, in find_class 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR __import__(module) 2019-08-05T15:34:41.54+0200 [APP/PROC/WEB/0] ERR ImportError: No module named joblib.numpy_pickle

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

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

functions.auth.user().onCreate()

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

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

我遇到的问题虽然出在我的App中,但我基于 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

我的问题是,当您更改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> ); } 函数也不具有更新的属性。仅当您重新加载整个应用程序时才会发生这种情况。

有人知道我可以在这里取得进步的方法吗?由于currentUser对象不会更新,因此路由中断,并且用户直到重新加载应用程序后才能继续进行操作。

1 个答案:

答案 0 :(得分:3)

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

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

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