基于@nuxtjs/firebase的Facebook登录用户数据存储与查询问题咨询
基于@nuxtjs/firebase的Facebook登录及数据关联实现方案
前置配置
首先在Firebase控制台Auth的「设置」页开启允许使用同一电子邮件地址创建多个账户(如果需要同一邮箱分别登录则保持关闭,建议开启避免重复账号),同时在「登录方式」页确保Facebook登录已正确配置。
1. 用户基础信息存储实现
核心逻辑:以Firebase Auth生成的全局唯一uid作为用户数据的唯一主键,登录成功后将用户信息写入Firestore的users集合,同个用户无论用什么方式登录uid完全一致,不会出现数据分散。
代码修改(基于你提供的登录页逻辑)
<script> export default { data: () => ({ email: '', password: '', }), methods: { // 存储用户公共方法 async saveUserInfo(authUser, provider) { const userRef = this.$fire.firestore.collection('users').doc(authUser.uid) // 用merge方式写入,不会覆盖用户后续自定义的字段 await userRef.set({ uid: authUser.uid, email: authUser.email, displayName: authUser.displayName, photoURL: authUser.photoURL, lastLoginTime: this.$fireModule.firestore.FieldValue.serverTimestamp(), loginProvider: provider }, { merge: true }) }, async loginUser() { try { const { user } = await this.$fire.auth.signInWithEmailAndPassword( this.email, this.password ) // 登录成功后写入用户信息 await this.saveUserInfo(user, 'email') this.$router.replace({ name: 'test1' }) } catch (e) { console.error(e) } }, async loginWithFacebook() { try { const provider = new this.$fireModule.auth.FacebookAuthProvider() // 申请邮箱权限,避免Facebook返回空邮箱 provider.addScope('email') const { user } = await this.$fire.auth.signInWithPopup(provider) // 登录成功后写入用户信息 await this.saveUserInfo(user, 'facebook') this.$router.replace({ name: 'test1' }) } catch (e) { console.error(e) } }, }, } </script>
对应Firestore安全规则配置
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 用户只能读写自己的信息 match /users/{uid} { allow read, write: if request.auth != null && request.auth.uid == uid; } } }
2. 用户操作行为(下单等)的记录与关联
必须记录的核心字段
所有用户操作类数据都必须携带uid作为关联主键,以下单场景为例,需记录的内容:
- 关联字段:uid、用户昵称(冗余存储减少跨表查询)、用户邮箱
- 订单字段:订单编号、下单时间、商品列表、总金额、支付状态、收货信息、订单状态
- 溯源字段:登录渠道(facebook/email)、操作IP、设备信息(可选)
存储实现示例(创建订单)
async createOrder(orderData) { // 从当前登录状态直接取uid,无需前端传递避免伪造 const currentUser = this.$fire.auth.currentUser if (!currentUser) return alert('请先登录') const orderRef = this.$fire.firestore.collection('orders').doc() await orderRef.set({ orderId: orderRef.id, uid: currentUser.uid, userName: currentUser.displayName, userEmail: currentUser.email, createTime: this.$fireModule.firestore.FieldValue.serverTimestamp(), ...orderData // 传入的商品、金额等订单信息 }) }
关联逻辑说明
Firebase Auth为每个用户生成的uid永久唯一,即使用户后续更换绑定邮箱、切换Facebook/邮箱登录方式,只要是同一个账号,uid就不会变化,按uid查询即可拉取该用户所有历史操作数据,不会出现关联失败的情况。
3. 管理员调取数据实现
前置配置
在users集合中对管理员账号的文档添加isAdmin: true字段,标识管理员身份。
安全规则配置(新增)
match /orders/{orderId} { // 用户只能看自己的订单,管理员可以看所有订单 allow read: if request.auth != null && (request.auth.uid == resource.data.uid || get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true) allow write: if request.auth != null && request.auth.uid == resource.data.uid } // 管理员可以查看所有用户信息 match /users/{uid} { allow read: if request.auth != null && (request.auth.uid == uid || get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true) allow write: if request.auth != null && request.auth.uid == uid }
调取代码示例
// 管理员获取所有用户列表 async getAllUsers() { const userSnapshot = await this.$fire.firestore.collection('users').get() return userSnapshot.docs.map(doc => doc.data()) } // 管理员获取指定用户的所有订单 async getUserOrders(uid) { const orderSnapshot = await this.$fire.firestore.collection('orders').where('uid', '==', uid).orderBy('createTime', 'desc').get() return orderSnapshot.docs.map(doc => doc.data()) } // 管理员获取所有订单 async getAllOrders() { const orderSnapshot = await this.$fire.firestore.collection('orders').orderBy('createTime', 'desc').get() return orderSnapshot.docs.map(doc => doc.data()) }
内容的提问来源于stack exchange,提问作者Boom
相关产品推荐
相关产品推荐

