Couchbase同步函数:如何获取有权访问指定频道的所有用户
嘿,我完全懂你的需求——当新文档被分配到某个频道时,你想先快速拿到这个频道的所有授权用户ID数组,接着给这些用户发APNS推送,而且你还希望能像var usr_arr = channel(the_channel).users();这么简洁地实现调用对吧?
可惜Sync Gateway原生并没有提供这么直接的内置方法,但我们可以通过几种实用的方案来达成目标:
方案一:调用Sync Gateway REST API查询
你可以利用Sync Gateway的**/_user**端点,通过频道过滤条件获取所有有权访问目标频道的用户。只需要发送一个GET请求,带上频道参数即可:
GET /{你的数据库名}/_user?channels={目标频道名}
这个请求会返回包含所有符合条件用户的JSON响应,你可以从中提取出用户ID组成数组。如果是在应用代码里实现,比如用Node.js,你可以用fetch或者axios发起请求,然后解析返回的数据得到用户列表。
方案二:在Sync Function中维护频道-用户映射
如果想要更高效的本地调用(避免每次都发起API请求),可以在Sync Function里维护一个全局的映射表,实时记录每个频道对应的授权用户集合:
- 当给用户授予频道权限时(比如执行
channel(目标频道).grant(用户ID)),同步把该用户ID添加到映射表对应的频道集合中 - 当移除用户的频道权限时,也要同步从集合中删除该用户ID
- 之后需要获取频道用户时,直接访问这个映射表就能拿到用户数组
举个简单的Sync Function示例:
// 全局维护频道与用户的映射关系 var channelUsers = {}; function sync(doc, oldDoc, meta) { // 处理文档的频道分配逻辑... // 示例:通过文档中的指令处理用户授权 if (doc.grantChannel) { var targetChannel = doc.grantChannel; var userId = doc.userID; // 授予用户频道访问权限 channel(targetChannel).grant(userId); // 更新映射表 if (!channelUsers[targetChannel]) { channelUsers[targetChannel] = new Set(); } channelUsers[targetChannel].add(userId); } // 当有新文档要推送到频道时,获取用户列表 if (doc.type === "newContent" && doc.targetChannel) { var targetUsers = Array.from(channelUsers[doc.targetChannel] || []); // 这里可以调用你的APNS推送逻辑,传入targetUsers数组 } }
需要注意的是,Sync Gateway重启后全局变量会被清空,所以最好把这个映射数据持久化到一个专门的文档里,在网关启动时加载进来,避免数据丢失。
方案三:维护外部映射数据库
如果你的系统是多实例部署的Sync Gateway,或者希望映射数据更稳定,也可以在调用Sync Gateway Admin API授予/移除用户频道权限时,同时在外部数据库(比如Redis、MongoDB)里维护一份用户-频道映射表。之后需要获取频道用户时,直接查询这个外部数据库即可,这种方式扩展性和稳定性都更好。
最后,你想要的那种极简调用方式虽然原生不支持,但可以自己封装一个工具函数,比如在应用代码里写一个getChannelUsers(targetChannel),内部根据你选择的方案实现逻辑,返回用户ID数组,用起来就和你期望的channel(the_channel).users();差不多啦。
内容的提问来源于stack exchange,提问作者Sean Mayes

