我有一个简单的应用程序,用户 A 可以向另一个用户 B 发送通知(聊天、点赞、评论),显然,用户 B 可以接收和阅读这些通知。
我的 firestore 数据库集合如下所示:
/Notifications/{userId}/NotificationItems/{notificationId}
其中
Notifications
和 NotificationItems
是集合,userId
是接收通知的用户的 if。 notificationId
是一个文档,其中包含有关通知的信息。
我的集合结构对我来说似乎很合理,所以最初我的 Firestore 规则是这样的:
match /Notifications/{userId}{
match /NotificationItems/{notificationId} {
allow create: if isUserAuthenticated();
allow read: if isUserAuthenticated() && userOwnsResource(userId);
allow update: if isUserAuthenticated() && userOwnsResource(userId);
}
}
其中函数
userAuthenticated
和 userOwnsResource
如下:
function isUserAuthenticated() {
return request.auth.uid != null;
}
function userOwnsResource(userId) {
return request.auth.uid == userId;
}
这些功能已经足够好了,我可以获取通知、发送通知、将其显示为可见等。
问题是我是否想发送
chat
通知类型。如果我想发送聊天通知,首先,我想检查我之前是否发送过聊天通知。如果我过早发送聊天通知,我不会发送新的通知。我拨打的 Firestore 电话:
await firebase
.firestore()
.collection("Notifications")
.doc(userId) //I dont have access to this user notifications as per the above rules
.collection("NotificationItems")
.where("chatId", "==", chatId)
.orderBy("date", "desc")
.get()
显然,这个调用失败了。我想通过实现一些功能来修复它,例如:
function itIsChatNotification(){
let chatId = get(/databases/$(database)/documents/Notifications/$(userId)/NotificationItems/$(notificationId)).data.chatId;
return request.auth.uid in get(/databases/$(database)/documents/Chats/$(chatId)).data.users;
}
即检查是否是聊天通知类型,获取该通知的chatId,然后检查该用户ID是否属于创建该聊天的用户。
然后将我的
read
访问权限更改为 allow read: if isUserAuthenticated() && (userOwnsResource(userId) || itIsChatNotification());
不用说,上面的功能不起作用,我不知道为什么。
我的聊天通知类型包含
authorId
、body
、type
(等于 chat
)、chatId
和 date
字段。
如果有人可以帮助编写正确的 Firestore 规则,那就太好了!
试试这个
match /Notifications/{userId}{
match /NotificationItems/{notificationId} {
allow create: if isUserAuthenticated();
allow read: if isUserAuthenticated() && (userOwnsResource(userId) || itIsChatNotification());
allow update: if isUserAuthenticated() && userOwnsResource(userId);
}
}
function isUserAuthenticated() {
return request.auth.uid != null;
}
function userOwnsResource(userId) {
return request.auth.uid == userId;
}
function itIsChatNotification() {
let chatId = resource.data.chatId;
let chatRef = /databases/$(database)/documents/Chats/$(chatId);
let chatDoc = get(chatRef).data;
return request.auth.uid in chatDoc.users;
}