尽管用户已登录,但为什么我的 Firebase 项目的规则设置中“request.auth”始终等于“null”?

问题描述 投票:0回答:1

这些是我在 firebase firestore 中的安全规则:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

这是我的自定义挂钩,用于监听用户身份验证并根据此身份验证进行数据获取:

import { useEffect, useState } from "react";
import { auth } from "./config";
import { onAuthStateChanged } from "firebase/auth";
import { getUserData } from "../actions/userActions";

function useAuth() {
  const [user, setUser] = useState<any>(undefined);
  const [uid, setUid] = useState<any>(undefined);
  const [firstName, setFirstName] = useState<any>(undefined);
  const [lastName, setLastName] = useState<any>(undefined);
  const [displayName, setDisplayName] = useState<any>(undefined);
  const [email, setEmail] = useState<any>(undefined);
  const [phone, setPhone] = useState<any>(undefined);
  const [address, setAddress] = useState<any>(undefined);
  const [role, setRole] = useState<any>(undefined);

  useEffect(() => {
    const fetchUserData = async (user: any) => {
      let userData = await getUserData(user.uid);
      if (userData) {
        setUid(userData.uid);
        setFirstName(userData.firstName);
        setLastName(userData.lastName);
        setDisplayName(userData.displayName);
        setEmail(userData.email);
        setPhone(userData.phone);
        setAddress(userData.address);
        setRole(userData.role);
      }
    };

    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (user) {
        setUser(user);
        fetchUserData(user);
      } else {
        setUser(undefined);
        setUid(undefined);
        setFirstName(undefined);
        setLastName(undefined);
        setDisplayName(undefined);
        setEmail(undefined);
        setPhone(undefined);
        setAddress(undefined);
        setRole(undefined);
      }
    });
    return () => unsubscribe();
  });

  return {
    user,
    uid,
    firstName,
    lastName,
    displayName,
    email,
    phone,
    address,
    role,
  };
}

export default useAuth;

这是“getUserData”函数:

export const getUserData = async (uid: string) => {
  try {
    const snapshot = await getDoc(doc(firestore, "users", uid));
    if (snapshot) return snapshot.data();
    else return undefined;
  } catch (e) {
    console.error("Error at 'getUserData': " + e);
    return undefined;
  }
};

然后在客户端我只需这样做:

const {user} = useAuth()
并在标签中使用用户对象:
<p>{user.uid}</p>

如果没有设置安全规则,身份验证和数据获取工作正常,但是一旦我设置了规则(如上面的示例),我就会收到错误:

FirebaseError: [code=permission-denied]: Missing or insufficient permissions.
尽管我认为在用户完全登录之前没有数据库提取。 如果我将规则更改为:
allow read, write: if true;
或者
allow read, write: if request.auth == null;
一切都按预期进行。

为什么用户登录时“request.auth”没有正确的值?

  • 将规则更改为“request.auth.uid”
  • 清除缓存
  • 使用规则游乐场来查看规则是否适合我想要的
  • 在代码中添加更多条件,以确保在用户登录之前不会进行任何提取
firebase next.js google-cloud-firestore firebase-security permission-denied
1个回答
0
投票

令我惊讶的是,您的

getUserData()
方法在某些情况下会返回一些数据,因为使用
DocumentSnapshot
检查
snapshot
if (snapshot)
对象)不为空应该始终返回
true

来自文档

注意:如果 docRef 引用的位置没有文档, 生成的文档将为空并且调用它上的存在将 返回错误。

您需要按照

文档
中的说明使用if (snapshot.exists()),即:

export const getUserData = async (uid: string) => {
  try {
    const snapshot = await getDoc(doc(firestore, "users", uid));
    if (snapshot.exists()) return snapshot.data();
    else return undefined;
  } catch (e) {
    console.error("Error at 'getUserData': " + e);
    return undefined;
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.