我需要使用userID安全地写入Firestore数据库吗?



我设置了以下Firestore安全规则:

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userID} {
allow create;
allow read, write: if request.auth.uid == userID;
}
}
}      

我试图保存用户的电子邮件,他们在我的SwiftUI应用程序中输入一个文本字段,以及应用程序生成的一个随机单词。两者都是字符串值:

db.collection("wordOfDay").document(core.UID() ?? "").setData(["email": inputText, "word": Array(commonWords)[commonWordIndex].foreign ?? "", "date": todaysDate])

正如您所看到的,我试图使用用户的ID(core.UID() ??"),在他们第一次注册时生成并保存到UserDefaults中,作为使用Firestore规则进行身份验证的方式。

但是,数据永远不会被写入。

当我允许任何人访问数据库时:

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}

写成功。

我确定我有一个身份验证问题,因为我没有找到任何方法发送Firestore的安全规则的userID。

最后一个规则片段中的allow read, write: if true;意味着世界上任何人都可以对每个文档做任何他们想做的事情,包括删除它们。这可能不是你想要的。

第一组规则只允许UID匹配的用户访问文档,这是实现仅所有者访问的一个好例子。但是你的代码不符合这个要求。特别是你呼出的表达式:

core.UID() ?? ""

这表示:如果有一个core值(假设是一个用户),那么使用它的UID,否则使用空字符串。但是在你的代码中,一个空字符串不是一个有效的文档ID,而且你的规则也不允许。

相反,您应该检查core是否有一个值,并且只有在实际有用户登录时才访问用户的数据库文档:

if (core != null && core.UID() != null) {
db.collection("wordOfDay").document(core.UID()!).setData(...);
}