在我的应用程序中,当用户创建新帖子时,我会向用户的关注者发送推送通知。正如您在下面的代码中看到的,我需要从每个关注者的个人资料中查询一些其他设置,以获取他们的推送令牌并检查一些其他通知设置。如果用户有大量关注者(即 1000 个),恐怕每个用户个人资料的查询可能会成为瓶颈。
解决这个问题的最佳方法是什么?
// The cloud function to trigger when a post is created
exports.newPost = functions.database.ref('/posts/{postId}').onCreate(event => {
const postId = event.params.postId;
const post = event.data.val();
const userId = post.author;
let tokens = [];
let promises = [];
return admin.database().ref(`/followers/${userId}`).once('value', (followers) => {
followers.forEach((f) => {
let follower = f.key;
promises.push(
admin.database().ref(`users/${follower}`).once('value')
);
});
})
.then(() => {
return Promise.all(promises).then((users) => {
users.forEach((user) => {
const userDetails = user.val();
if (userDetails.post_notifications) {
if(userDetails.push_id != null) {
tokens.push(userDetails.push_id);
}
}
})
})
})
.then(() => {
if (tokens.length > 0) {
const payload = {
notification: {
title: 'New Post!',
body: 'A new post has been created'
}
};
// Send notifications to all tokens.
return admin.messaging().sendToDevice(tokens, payload);
}
});
})
编辑:
我们已经考虑过使用主题。但我们不确定如何仍然让我们的自定义通知设置处理主题。这是我们的困境。
我们有多个可以创建通知的操作,我们为应用中的每种通知类型提供单独的开关,以便用户可以选择要关闭的通知类型。
假设用户 A 跟随用户 B 时。我们可以将用户 A 订阅到"用户 B 的主题",因此每当用户 B 执行向其关注者发送通知的操作时,我都可以向订阅"用户 B 主题"的用户发送通知。
因为我们在应用程序中有多个通知开关,并且当用户 A 更改他/她的设置时,他们不希望收到新帖子的通知,但仍希望来自他/她关注的用户的其他类型的通知,因此我们无法弄清楚在这种情况下如何使用主题。
您可以使用主题,而不是使用令牌。因此,假设用户开始关注某人,然后他将注册该主题。
假设他跟踪了一个叫"彼得"的人,那么你可以执行这个:
FirebaseMessaging.getInstance().subscribeToTopic("Peter");
现在,如果您有此数据库:
posts
postid
postdetails: detailshere
author: Peter
然后使用onCreate()
:
exports.newPost = functions.database.ref('/posts/{postId}').onCreate(event => {
const postId = event.params.postId;
const post = event.data.val();
const authorname = post.author;
const details=post.postdetails;
const payload = {
data: {
title:userId,
body: details,
sound: "default"
},
};
const options = {
priority: "high",
timeToLive: 60 * 60 * 24
};
return admin.messaging().sendToTopic(authorname, payload, options);
});
您可以使用它,每次作者创建新帖子时,触发onCreate()
,然后您可以在通知中添加帖子的详细信息和作者姓名(如果需要),sendToTopic()
会将其发送给订阅该主题的所有用户,即authorname
(例如:Peter)
编辑后,我认为您希望用户取消订阅某个主题,但保持订阅其他主题,那么您必须为此使用 admin sdk:
https://firebase.google.com/docs/cloud-messaging/admin/manage-topic-subscriptions
使用管理员 sdk,您还可以取消订阅用户的主题,一个简单的示例:
// These registration tokens come from the client FCM SDKs.
var registrationTokens = [
'YOUR_REGISTRATION_TOKEN_1',
// ...
'YOUR_REGISTRATION_TOKEN_n'
];
// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
admin.messaging().unsubscribeFromTopic(registrationTokens, topic)
.then(function(response) {
// See the MessagingTopicManagementResponse reference documentation
// for the contents of response.
console.log('Successfully unsubscribed from topic:', response);
})
.catch(function(error) {
console.log('Error unsubscribing from topic:', error);
});