You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
      }
    }
  }
}

额外优化点

  1. 避免重复写入用户数据:登录逻辑中无需重复写入users集合,仅在注册时写入即可,减少不必要的Firestore操作。
  2. 修复Guest Login参数缺失:handleGuestLogin函数未定义e参数,会导致运行报错,需补充:
const handleGuestLogin = async (e) => { // 补充e参数
  e.preventDefault();
  // ...原有逻辑
}
  1. 复用Auth实例:登录组件中直接调用getAuth()会创建新实例,建议直接导入初始化文件中导出的auth实例,保持一致性。

内容的提问来源于stack exchange,提问作者Izk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:16:00