我的网络应用程序将具有基于"线程"one_answers"消息"的聊天功能。
在任何给定的线程中,都可以订阅2个或更多人的新消息通知。
任何给定的人都可以有多个设备,每个设备都有相应的FCM令牌(在获得向他们发送通知的许可后获得(。
假设我有一个线程"猫"有3个订阅者。文档结构如下:
id: "thread1"
title: "cats"
subscribers:["uid1","uid2","uid3"]
我为这三个用户存储了FCM令牌。文档结构如下:
id: "token1"
tokenOwner: "uid1"
id: "token2"
tokenOwner: "uid2"
id: "token3"
tokenOwner: "uid2"
id: "token4"
tokenOwner: "uid3"
id: "token5"
tokenOwner: "uid4"
要在thread1
中发送新消息的通知,我需要在FCM Tokens集合中查询tokenOwner
在所提供的数组["uid1","uid2","uid3"]
中的任何令牌。
这个查询看起来像这样:
db
.collection("fcmTokens")
.where('tokenOwner', 'in', ["uid1","uid2","uid3"])
.get()...
这在Cloud Firestore查询限制生效之前效果很好:
使用in运算符在具有逻辑OR的同一字段。in查询返回文档,其中给定字段匹配任何比较值。
在数组查询中最多只能包含10个uid。如果有12个人订阅了这个线程,我要么运气不好,要么需要运行多个查询,这似乎效率很低。
如何以"Firebase Friendly"的方式构建FCM代币?
针对这种情况运行多个查询并不是效率很低。所有请求都是通过单个连接进行流水线处理的,您应该能够通过快速连接在几毫秒内获得所有请求。新的"in"查询主要是为了方便不必执行多个查询,而不是为了优化(除非它阻止您从多个查询中多次获取同一文档(。您应该对现在的情况很满意——在实际观察到性能问题之前,不需要过早地对此进行优化。
就我个人而言,我会为根据用户UID组织的用户存储令牌,而不是将所有用户的令牌放在一个集合中。
Collection: user-tokens
Document ID: {uid}
- tokens: [ array of tokens for the user ]
然后,要获取用户的所有令牌,只需获取包含所有令牌的文档即可。
如果你担心用户可能使用数千台设备,令牌的数量可能超过单个文档的容量,那么将每个令牌存储在一个单独的文档中,并在整个子集合中查询用户的令牌:
Collection: user-tokens
Document ID: {uid}
Subcollection: tokens
Document ID: {random}
- token: string
在UID下组织令牌还可以更容易地编写安全规则,这样只有特定用户才能读取和写入自己的令牌(如果您希望控制的话(。