如何基于React Native Firebase实现Expo应用的邮箱链接无密码认证?
React Native Firebase 邮箱链接无密码认证实现方案
Firebase 没有提供单独的 createUserWithEmailLink 方法,因为邮箱链接认证本身是登录与注册一体化的流程:当用户通过邮件链接完成认证时,若该邮箱未注册过,Firebase 会自动创建对应的用户账号,无需额外调用创建用户的接口。以下是具体实现步骤:
1. 前置配置
- 登录 Firebase 控制台,进入「认证」→「登录方式」,启用「邮箱/密码」和「邮箱链接(无密码登录)」两种认证方式。
- 在「认证」→「设置」→「授权域」中添加你的应用关联域名(Expo 项目可填
exp://<你的项目ID>或自定义深度链接域名)。 - 在 Expo 项目的
app.json中配置scheme字段(例如"scheme": "yourapp"),确保应用能正确处理深度链接。
2. 发送认证邮件链接
使用 sendSignInLinkToEmail 方法向用户邮箱发送认证链接,同时存储待验证邮箱以便后续使用:
import auth from '@react-native-firebase/auth'; import AsyncStorage from '@react-native-async-storage/async-storage'; const sendAuthEmail = async (email) => { const actionCodeSettings = { url: 'exp://your-expo-app-url/verify-email', // 应用跳转链接 handleCodeInApp: true, // 必须设为true,由应用处理链接 iOS: { bundleId: 'com.your-app.bundle-id' }, android: { packageName: 'com.your-app.package-name', installApp: true, minimumVersion: '12' } }; await auth().sendSignInLinkToEmail(email, actionCodeSettings); await AsyncStorage.setItem('pendingAuthEmail', email); };
3. 处理应用内的链接跳转
通过 Expo 的 Linking API 监听深度链接,完成认证流程(自动处理登录/注册):
import * as Linking from 'expo-linking'; import auth from '@react-native-firebase/auth'; import AsyncStorage from '@react-native-async-storage/async-storage'; useEffect(() => { const handleAuthLink = async (url) => { const pendingEmail = await AsyncStorage.getItem('pendingAuthEmail'); if (!pendingEmail) return; // 验证链接是否为Firebase登录链接 if (auth().isSignInWithEmailLink(url)) { try { // 执行认证:邮箱未注册则自动创建账号 const userCredential = await auth().signInWithEmailLink(pendingEmail, url); await AsyncStorage.removeItem('pendingAuthEmail'); // 认证成功后的逻辑,比如跳转首页 console.log('认证成功,用户信息:', userCredential.user); } catch (err) { console.error('认证失败:', err.message); } } }; // 处理应用启动时的初始链接 Linking.getInitialURL().then(handleAuthLink); // 监听后续的链接跳转 const linkSubscription = Linking.addEventListener('url', ({ url }) => handleAuthLink(url)); return () => linkSubscription.remove(); }, []);
4. 监听用户认证状态
添加状态监听,实时获取用户登录状态:
import auth from '@react-native-firebase/auth'; useEffect(() => { const unsubscribe = auth().onAuthStateChanged(user => { if (user) { // 用户已登录/注册成功,可获取用户信息 console.log('当前用户:', user.email); } else { // 用户未登录 } }); return unsubscribe; }, []);
关键注意事项
actionCodeSettings中的url必须与 Firebase 控制台配置的授权域匹配,否则会导致链接无效。- iOS 模拟器中需手动复制邮件链接到应用,Android 可直接点击邮件链接跳转。
- 若用户多次请求链接,最新的链接会覆盖旧链接,旧链接将失效。
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

