Android端Firebase限制唯一邮箱ID及Google认证重复登录问题
解决Firebase Google认证的邮箱唯一性限制与重复存储问题
我来帮你搞定这两个Firebase认证的问题,刚好之前处理过类似场景,给你一步步拆解方案:
一、阻止已存在于Authenticated-Users节点的邮箱登录
Firebase默认允许任何有效的Google账号完成认证,客户端校验肯定不安全(很容易被绕过),必须用云函数的认证前置触发器来做服务器端校验,这是最可靠的方式。
步骤1:编写beforeCreate云函数
这个函数会在用户通过Google认证创建账号之前触发,检查目标邮箱是否已经在你的Authenticated-Users节点里存在:
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.blockExistingEmails = functions.auth.user().beforeCreate(async (user) => { const email = user.email; // 先判断邮箱是否存在(避免无邮箱的特殊Google账号) if (!email) { throw new functions.auth.HttpsError( "invalid-argument", "登录需要提供有效的邮箱地址" ); } // 查询数据库中是否已存在该邮箱 const userDbRef = admin.database().ref(`Authenticated-Users/${email}`); const snapshot = await userDbRef.once("value"); // 如果邮箱已存在,抛出错误阻止账号创建 if (snapshot.exists()) { throw new functions.auth.HttpsError( "already-exists", "该邮箱已在系统中注册,请更换其他邮箱登录" ); } });
步骤2:客户端捕获错误并提示用户
当云函数抛出错误时,客户端要捕获并给用户友好提示:
firebase.auth().signInWithPopup(new firebase.auth.GoogleAuthProvider()) .catch((error) => { // 匹配我们自定义的错误码 if (error.code === "auth/already-exists") { alert("这个邮箱已经被使用啦,请换个邮箱试试"); } else { console.error("登录出错了:", error); } });
二、解决退出后再次登录的重复存储问题
你提到退出后再次登录时的问题,推测是邮箱会被重复写入Authenticated-Users节点?解决这个的核心是只在用户首次创建账号时写入数据库,而不是每次登录都执行写入操作。
编写onCreate云函数
这个触发器只会在用户账号首次创建时触发,刚好用来将邮箱写入你的数据库节点:
exports.addNewUserToDb = functions.auth.user().onCreate(async (user) => { const email = user.email; if (email) { // 写入邮箱及必要的用户信息到Authenticated-Users节点 await admin.database().ref(`Authenticated-Users/${email}`).set({ uid: user.uid, createdAt: admin.database.ServerValue.TIMESTAMP }); } });
这样不管用户后续退出再登录多少次,都不会重复写入数据,完美解决重复存储的问题。
额外:确保数据库节点的安全性
为了防止客户端恶意篡改Authenticated-Users节点,一定要配置数据库规则,限制只有云函数(管理员权限)能写入:
{ "rules": { "Authenticated-Users": { ".read": false, // 如果业务需要客户端读取,可以改成true,但建议仅允许云函数操作 ".write": false // 云函数用admin SDK不受规则限制,所以直接禁用客户端写入 } } }
内容的提问来源于stack exchange,提问作者Niamatullah Bakhshi
相关产品推荐
相关产品推荐

