FirebaseError:应用程序中缺少或权限不足,但它在模拟中有效

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

以下是我的 Firestore 规则。我有一个“用户”集合,其中文档 ID 是身份验证中用户的 UID。我只希望管理员访问某些用户数据或用户本身。

service cloud.firestore {
  match /databases/{database}/documents {
    match /{users=**} {
      allow read: if  isOwner() || isAdmin();
      allow write: if isOwner();
    }
    
    function isOwner() {
      return request.auth != null && request.auth.uid == resource.id;
    }
    
    function isAdmin() {
        return request.auth != null && request.auth.token.user_type == 3;
    }
  }
}

这是我用来获取数据的函数:

const fetchUserDetails = async (userId: string) => {
    const userDocRef = doc(FIREBASE_DB, 'users', userId);
    console.log('Fetching userid: ', userId);
    const userDocSnapshot = await getDoc(userDocRef);

    if (userDocSnapshot.exists()) {
        const userData = userDocSnapshot.data();
        const addressesCollectionRef = collection(
            FIREBASE_DB,
            'users',
            userId,
            'addresses',
        );
        const addressesSnapshot = await getDocs(addressesCollectionRef);

        const addresses = addressesSnapshot.docs.map(addressDoc =>
            addressDoc.data(),
        );

        return {
            ...userData,
            addresses,
        };
    }
    // Handle the case where the user does not exist in Firestore
    console.error('User not found in Firestore');
    return null;
};

当我在 Firestore 中尝试模拟时,一切正常。管理员可以获取所有用户的信息,普通用户只能获取自己的信息。但是,当我尝试在 React Native 应用程序中使用上述代码获取用户数据时,我收到此错误:FirebaseError:缺少或权限不足。对于管理员来说它工作得很好,它可以获取自己的数据。但普通用户无法获取自己的数据。我检查到普通用户只尝试访问自己的数据而不是其他数据。

另外,如果我尝试将我的安全规则更改为此。现在连管理员都无法获取数据了。

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    
    match /users/{userId} {
      allow read: if  isOwner(userId) || isAdmin();
      allow write: if isOwner(userId);
    }
    
    function isOwner(userId) {
      return request.auth != null && request.auth.uid == userId;
    }
    
    function isAdmin() {
        return request.auth != null && request.auth.token.user_type == 3;
    }
  }
}
firebase google-cloud-platform google-cloud-firestore firebase-authentication firebase-security
1个回答
0
投票

如果您希望

isOwner()
在使用以下代码行读取数据时工作:

const userDocRef = doc(FIREBASE_DB, 'users', userId);
const userDocSnapshot = await getDoc(userDocRef);

那么你必须将规则更改为:

service cloud.firestore {
  match /databases/{database}/documents {
    //            👇
    match /users/{uid} {
      allow read: if  isOwner() || isAdmin();
      allow write: if isOwner();
    }
    
    function isOwner(uid) {
      return request.auth != null && request.auth.uid == uid;
    }
    
    function isAdmin() {
        return request.auth != null && request.auth.token.user_type == 3;
    }
  }
}

通过这种方式,您将确保您的用户只能读取和写入他们的自己的数据。

请注意,您可以将安全规则级联到嵌套子集合。因此,如果您希望能够读取

addresses
子集合下的数据,那么您必须在文档 ID 的 match 子句中指定递归通配符
(=**)
。由于您对
users
集合执行此操作,因此您当前的访问规则不会级联。所以你必须使用类似的东西:

service cloud.firestore {
  match /databases/{database}/documents {
    //               👇
    match /users/{uid=**} {
      allow read: if  isOwner(uid) || isAdmin(uid);
      allow write: if isOwner(uid);
    }
    
    function isOwner(uid) {
      return request.auth != null && request.auth.uid == uid;
    }
    
    function isAdmin() {
        return request.auth != null && request.auth.token.user_type == 3;
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.