修复NextAuth+Firebase获取用户数据时的权限不足错误
问题描述
我正在使用NextAuth和Firebase获取用户数据,但调用getBalance函数时出现错误:
Uncaught (in promise) FirebaseError: Missing or insufficient permissions
以下是相关代码及配置:
函数代码
async function getBalance(uid) { const userRef = doc(db, "users", uid); const userDoc = await getDoc(userRef); if (userDoc.exists()) { const { tokens } = userDoc.data(); return tokens; } else { return null; } }
Firebase Admin配置
import { getApps } from "firebase-admin/app"; import admin from "firebase-admin"; const serviceAccount = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT_KEY); if (!getApps().length) { admin.initializeApp({ credential: admin.credential.cert(serviceAccount), }); } const adminDb = admin.firestore(); const adminAuth = admin.auth(); export { adminDb, adminAuth };
Firebase客户端配置
import { getFirestore } from "firebase/firestore"; import { getApps, initializeApp } from "firebase/app"; const firebaseConfig = { apiKey: process.env.FIREBASE_APIKEY, authDomain: process.env.FIREBASE_AUTHDOMAIN, databaseURL: process.env.FIREBASE_DATABASEURL, projectId: process.env.FIREBASE_PROJECTID, storageBucket: process.env.FIREBASE_STORAGEBUCKET, messagingSenderId: process.env.FIREBASE_MESSAGINGSENDERID, appId: process.env.FIREBASE_APPID, measurementId: process.env.FIREBASE_MEASUREMENTID, }; const app = getApps().length ? getApp() : initializeApp(firebaseConfig); const db = getFirestore(app); export { db };
数据库结构
/users/email@example.com/chats/UN3XookDLjiJvqsW7GPG/messages/2gKLNAKDGiNWy2TvcFWq
(其中email@example.com为用户uid)
当前Firestore规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if request.auth.uid == userId; match /{document=**} { allow read, write: if request.auth.uid == userId; } } } }
测试规则(可正常运行)
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.time < timestamp.date(2023, 4, 19); } } }
请问需如何修改Firebase规则以允许访问用户数据?
解决方案
问题核心是规则校验逻辑与实际用户ID的存储方式不匹配,结合你的场景可按以下方式修复:
1. 调整Firestore规则适配邮箱格式的用户ID
你的数据库中用户文档ID是邮箱地址,但默认request.auth.uid是Firebase Auth生成的唯一标识符(非邮箱),因此需要修改规则的校验条件:
修改后的规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 匹配/users下的所有层级(包括子集合chats、messages) match /users/{userId}/{document=**} { allow read, write: if request.auth != null && request.auth.token.email == userId; } } }
规则说明
- 直接覆盖
/users/{userId}下的所有文档和子集合,避免嵌套匹配的冗余 - 用
request.auth.token.email替代request.auth.uid,与你存储的邮箱格式用户ID匹配 - 增加
request.auth != null校验,确保用户已完成认证
2. 确保客户端请求携带有效认证信息
调用getBalance时需确认:
- 用户已通过NextAuth完成登录,且当前会话有效
- 传入的
uid参数与Firebase Auth返回的用户邮箱完全一致(大小写、拼写无误差)
3. 备选优化:改用Firebase Auth的uid作为用户文档ID
如果是误将邮箱设为用户文档ID,建议改为使用Firebase Auth生成的uid作为文档ID:
- 用户创建时,用
adminAuth.createUser返回的uid作为/users下的文档ID - 保持你原有的Firestore规则即可生效,此时
request.auth.uid与userId完全匹配
内容的提问来源于stack exchange,提问作者Tui
相关产品推荐
相关产品推荐

