如何在使用 firebase/auth 和 react-native 验证他/她的电子邮件后立即登录用户而不创建整个登录页面?
Posted
技术标签:
【中文标题】如何在使用 firebase/auth 和 react-native 验证他/她的电子邮件后立即登录用户而不创建整个登录页面?【英文标题】:How can I log in a user right after his/her email has been verified using firebase/auth and react-native without creating a whole landing page? 【发布时间】:2021-12-23 06:11:09 【问题描述】:注意:我见过this question,但是创建一个完整的登录页面只是为了验证用户似乎有点过分。
我使用 firebase/auth
以及电子邮件和密码向我的 react-native 应用程序添加了登录功能。到目前为止效果很好,我没有问题。
然后,我继续向新用户发送验证电子邮件,并且仅在电子邮件通过验证后才允许他/她使用该应用程序。同样,这里没有问题。
下一步是在验证电子邮件后立即登录用户。这就是我卡住的地方,因为在用户按下电子邮件中的验证链接后,onAuthStateChanged
事件处理程序不会更新。
有没有办法实时收听emailVerified
状态?我尝试使用setInterval()
进行轮询,但这并不是很好,因为验证和登录之间存在明显的延迟。我读到了一个可以传递给sendEmailVerification
的 continueLink,但我不知道如何在 react-native 中实现它。
我使用的是Expo
,因此使用的是 Firebase SDK,而不是 Firebase 反应原生包。
这是我用于注册的代码:
export const signUp = async (username: string, email: string, password: string) =>
try
const auth = getAuth();
if (email && password && username)
// sign up
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
// save username in firestore
await setUserName(userCredential, username);
// send Email Verification
await sendEmailVerification(userCredential.user);
return true;
catch (error)
onError(error);
;
这是我的 onAuthStateChanged 处理程序:
auth.onAuthStateChanged(authenticatedUser =>
try
if (authenticatedUser?.emailVerified)
setUser(authenticatedUser)
else
setUser(null)
catch (error)
console.log(error);
);
【问题讨论】:
【参考方案1】:所以最后我确实关注了this question,但我对其进行了一些更改以满足我的需要。我会将我的步骤发布给任何这样做的人。
-
使用
firebase init
创建一个简单的静态网站,并将其托管在 Firebase 或其他地方(检查您的 Firebase 控制台中的托管选项卡以开始使用)
关注this guide 在网站上创建相应的处理程序
将以下内容添加到您的 verificationHandler
以更新用户(不要忘记导入 firestore)(我通过 continueURL
发送 userId,但可能有更好的方法)
// You can also use realtime database if you want
firebase.firestore().collection("users").doc(userId).set(
emailVerified: true
, merge: true).then(() =>
message.textContent = "Your email has been verified.";
).catch((error) =>
message.textContent = "The verification was invalid or is expired. Please try to send another verification email from within the app.";
);
-
进入身份验证 -> Firebase 控制台中的模板并将操作 url 更改为托管网站的 url
为您的 react-native 应用添加一个到 firestore 文档的侦听器
const onUserDataChanged = (uid, callback) =>
onSnapshot(doc(firestore, "users", uid), doc => callback(doc.data()));
-
使用回调中的数据更新应用中的登录状态
// As an example
auth.onAuthStateChanged(authenticatedUser =>
if (authenticatedUser && !authenticatedUser.emailVerified)
unsubscribeFirestoreListener?.();
unsubscribeFirestoreListener = onUserDataChanged(authenticatedUser.uid, (data: any) =>
if (data?.emailVerified)
setUser(authenticatedUser);
unsubscribeFirestoreListener?.();
);
【讨论】:
【参考方案2】:将以下代码用于您的身份验证上下文。对于用户 ID,您应该使用 'user.uid'
import React, useState, createContext from "react";
import * as firebase from "firebase";
import loginRequest from "./authentication.service";
export const AuthenticationContext = createContext();
export const AuthenticationContextProvider = ( children ) =>
const [isLoading, setIsLoading] = useState(false);
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
firebase.auth().onAuthStateChanged((usr) =>
if (usr)
setUser(usr);
setIsLoading(false);
else
setIsLoading(false);
);
const onLogin = (email, password) =>
setIsLoading(true);
firebase.auth().signInWithEmailAndPassword(email, password)
.then((u) =>
setUser(u);
setIsLoading(false);
)
.catch((e) =>
setIsLoading(false);
setError(e.toString());
);
;
const onRegister = (email, password, repeatedPassword) =>
setIsLoading(true);
if (password !== repeatedPassword)
setError("Error: Passwords do not match");
return;
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((u) =>
setUser(u);
setIsLoading(false);
)
.catch((e) =>
setIsLoading(false);
setError(e.toString());
);
;
const onLogout = () =>
setUser(null);
firebase.auth().signOut();
;
return (
<AuthenticationContext.Provider
value=
isAuthenticated: !!user,
user,
isLoading,
error,
onLogin,
onRegister,
onLogout,
>
children
</AuthenticationContext.Provider>
);
;
【讨论】:
以上是关于如何在使用 firebase/auth 和 react-native 验证他/她的电子邮件后立即登录用户而不创建整个登录页面?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Firebase/Auth 上避免 UIWebView
如何观察 firebase.auth().currentUser.displayName 和其他属性的变化?
如何将来自不同组件的 firebase auth 和 Cloud Firestore 用作单个 Firebase 应用程序
如何在使用 firebase/auth 和 react-native 验证他/她的电子邮件后立即登录用户而不创建整个登录页面?