在 Cloud Firestore 规则中,request.auth.uid 似乎始终为空

Posted

技术标签:

【中文标题】在 Cloud Firestore 规则中,request.auth.uid 似乎始终为空【英文标题】:request.auth.uid seems to always be null in Cloud Firestore rules 【发布时间】:2018-10-17 21:30:06 【问题描述】:

我必须在这里遗漏一些非常基本的东西......但是每当我调用我的 Cloud Firestore 数据库并尝试制定任何类型的安全规则时,它们总是会失败。

做类似的事情

    match /users/userId 
      allow create, read, update: if true;
    

有效,但它显然违背了这一点。但是,如果我进行任何形式的额外审查,例如所有文档中的首选示例,例如

    match /users/userId 
      allow create, read, update: if request.auth.uid != null;
    

每次都失败。我在如何将客户端代码连接在一起时是否遗漏了一些明显的东西?

这是我的客户端代码,它让用户登录,然后调用数据库来获取用户。 (请注意,在我的数据库中,用户的密钥是通过电子邮件,而不是通过 uid)

// this is a snippet from the code where I log the user in
firebase.auth().signInWithEmailAndPassword(email, FIREBASE_USER_PASSWORD)
            .then(user => 
            // the user comes back successfully logged in, 
            // I grab its uid and add it to a preparedUser object that I've been building, 
            // then pass this user to my getFirestoreUserObject function
                preparedUser.uid = user.uid;
                getFirestoreUserObject(dispatch, user: preparedUser, navigate);
            )
            
// then the getFirestoreUserObject function:
// note that all the code below works fine when there are no security rules in place

const getFirestoreUserObject = (dispatch, user, navigate) => 
    const name, email, imageUrl = user;
    // if I ask for currentUser here, I get back my logged in user
    const currentUser = firebase.auth().currentUser;

    // email is defined correctly here as the user's email
    firebase.firestore().collection('users').doc(`$email`)
        .get() // the request fails here due to insufficient permissions
        .then(doc => 
            if (doc.exists) 
                const currentUser = doc.data();

                getUserFavorites(dispatch, currentUser, navigate);
             else 
                createUserInFirestore(dispatch, user, navigate);
            
        )
;

我有什么明显的遗漏吗?如果我通过firebase.auth() 登录用户,然后在调用firebase.firestore() 之后立即登录,那不应该有经过身份验证的用户的上下文吗?如果没有,我如何将其传递给 firestore 调用?

谢谢!

【问题讨论】:

我认为这里的问题是“紧接着”。就像使用 firebase 登录的一切都是异步的一样,所以它需要(很短)一段时间才能完成。 谢谢,@AndréKool。在成功的 auth .then() 块之后进行 db 调用的事实不应该意味着 firebase 方面的工作已经完成吗?另外,在我上面的 sn-p 中,当我调用 currentUser 时,在我接触到数据库之前,我成功地从 firebase.auth() 取回了 currentUser。 【参考方案1】:

经过数周的搜索,firestore 和 auth 都独立工作但没有一起工作......这是最简单的事情。

我使用的是 firebase 4.x,这是我开始项目时可用的最新版本。然后,当我开始添加身份验证规则时,关于如何执行 db 规则的最新发布的关于 firebase 的文档(我开始时甚至没有看过,但几个月后我准备实施它们时又回来了) 使用 firebase 5.y 列出。更新了我的 package.json、npm install,一切都神奇地工作了 :(

希望这可以帮助其他人...确保您至少使用第 5 版!

使用以下命令更新模拟器:npm install -g firebase-tools

【讨论】:

我在使用 'com.google.firebase:firebase-firestore:17.1.0'android 上遇到了同样的问题。 @AdamHurwitz 这个问题你解决了吗?【参考方案2】:

我遇到了同样的问题,但最终对我有用的是通过运行npm install -g firebase-tools 更新firebase cli,这反过来又更新了cloud firestore emulator

注意:根据您使用的安装方法,更新 Firebase cli 的方法可能有所不同。如果您使用npm 安装firebase cli,上述解决方案将起作用。有关更新 firebase cli 的其他方法,请参阅firebase docs。

【讨论】:

【参考方案3】:

2021 年 6 月

firebase cli 9.12.1 仍然存在问题。

必须将 firebase JS 降级到 8.3.1 才能使其工作,但使用该版本它会尝试在线验证用户,而不是使用模拟器

见this post

【讨论】:

【参考方案4】:

您应该使用firebase.firestore().collection('users').doc(`$currentUser.uid`).get() 而不是firebase.firestore().collection('users').doc(`$email`).get()

这是因为您的安全规则

match /users/userId 
  allow create, read, update: if request.auth.uid != null;

在确定是否向用户提供数据访问权限时检查用户的 uid,而不是用户的电子邮件。

希望有所帮助。

【讨论】:

感谢您的建议。我的用户是通过电子邮件组织的,因此我可以从控制台上的 firestore 列表视图中分辨出他们是谁,而无需深入研究每个单独的文档。这个问题最终成为版本控制问题:(我在上面留下了更新的答案。再次感谢

以上是关于在 Cloud Firestore 规则中,request.auth.uid 似乎始终为空的主要内容,如果未能解决你的问题,请参考以下文章

Cloud Firestore 忽略规则

在 Cloud Firestore 规则中,request.auth.uid 似乎始终为空

Firebase Cloud Storage 规则能否针对 Firestore 数据进行验证?

Cloud Firestore 安全规则 -(读取、写入)

使用规则禁用 Firebase Cloud Firestore 中的查询集合

使用 exists() 的 Cloud Firestore 规则是不是算作读取?