Firebase权限拒绝错误:注册时无法存储用户数据求助
Firebase权限错误排查:permission-denied问题分析
问题场景
点击注册按钮时触发Firebase权限错误:FirebaseError: [code=permission-denied]: Missing or insufficient permissions,调整Firebase规则以允许用户数据存储后问题仍存在,项目同时集成Stripe。
相关代码
Firebase规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /customers/{uid} { allow read, write: if request.auth.uid == uid; match /checkout_sessions/{id} { allow read, write: if request.auth.uid == uid; } match /subscriptions/{id} { allow read: if request.auth.uid == uid; } match /payments/{id} { allow read: if request.auth.uid == uid; } match /users/{userId} { allow read, write: if request.auth.uid == userId; } } match /products/{id} { allow read: if true; match /prices/{id} { allow read: if true; } match /tax_rates/{id} { allow read: if true; } } } }
登录组件核心代码
import { doc, setDoc } from "firebase/firestore"; import { auth, db } from "@/firebase"; // ...其他导入 export default function LoginModal() { // ...状态与实例定义 const handleSignup = async (e) => { e.preventDefault(); try { await setPersistence(auth, browserLocalPersistence); const userCredentials = await createUserWithEmailAndPassword(auth, email, password); const user = userCredentials.user; if (user) { // 向根路径users集合写入数据 await setDoc(doc(db, "users", user.uid), { email: user.email, uid: user.uid, }); goToForYouPage(); } } catch (error) { console.error("error", error); } }; // ...其他登录逻辑 }
Firebase初始化代码
import { initializeApp } from "firebase/app"; import { getFirestore } from "firebase/firestore"; import { getAuth } from "firebase/auth"; const firebaseConfig = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, }; const app = initializeApp(firebaseConfig); const auth = getAuth(app); const db = getFirestore(app); export { db, auth };
核心问题定位
Firebase规则中,/users集合的规则被嵌套在/customers/{uid}路径下,而代码中是直接向根路径的/users集合写入数据,导致规则匹配失败,权限被拒绝。
修复方案
调整Firebase规则,将/users集合的规则移到根路径下,与/customers、/products同级:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /customers/{uid} { allow read, write: if request.auth.uid == uid; match /checkout_sessions/{id} { allow read, write: if request.auth.uid == uid; } match /subscriptions/{id} { allow read: if request.auth.uid == uid; } match /payments/{id} { allow read: if request.auth.uid == uid; } } // 将users规则移至根路径,匹配代码中的写入路径 match /users/{userId} { allow read, write: if request.auth.uid == userId; } match /products/{id} { allow read: if true; match /prices/{id} { allow read: if true; } match /tax_rates/{id} { allow read: if true; } } } }
额外优化点
- 避免重复写入用户数据:登录逻辑中无需重复写入
users集合,仅在注册时写入即可,减少不必要的Firestore操作。 - 修复Guest Login参数缺失:
handleGuestLogin函数未定义e参数,会导致运行报错,需补充:
const handleGuestLogin = async (e) => { // 补充e参数 e.preventDefault(); // ...原有逻辑 }
- 复用Auth实例:登录组件中直接调用
getAuth()会创建新实例,建议直接导入初始化文件中导出的auth实例,保持一致性。
内容的提问来源于stack exchange,提问作者Izk
相关产品推荐
相关产品推荐

