我已经成功设置了 firebase 云功能来向主题发送通知。问题是它发送给包括发件人在内的所有用户,我如何设置我的云功能以便它不向发件人显示通知?请帮忙?下面是如何发送到主题
exports.sendNotesNotification = functions.database.ref('/Notes/{pushId}')
.onWrite(event => {
const notes = event.data.val();
const payload = {
notification: {
username: notes.username,
title: notes.title,
body: notes.desc
}
}
admin.messaging().sendToTopic("New_entry", payload)
.then(function(response){
console.log("Successfully sent notes: ", response);
})
.catch(function(error){
console.log("Error sending notes: ", error);
});
});
最佳答案
来自 firebase 的文档,对于公开且时间不紧迫的通知,应使用主题发送通知。在您的情况下,通知不是公开的,并且由于发件人也订阅了该特定主题,他也将收到通知。 因此,如果您想避免向发件人发送通知,您必须取消该发件人对您主题的订阅。
或者更好的解决方案是您应该使用 FCM token 将通知发送到单个设备。 用于发送 FCM token 通知的 node.js 代码是
admin.messaging().sendToDevice(<array of tokens>, payload);
您可以从 Android 的 FirebaseInstanceIdService 的 onTokenRefresh() 方法获取设备 token 。
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
// TO DO: send token to your server or firebase database
}
更新:
将 firebase token 存储到您的数据库现在您应该像这样构建您的数据库
-users
|-user1uid
| |-name //your choice
| |-email //your choice
| |-fcmTokens
| |-valueOftoken1:true
| |-valueOftoken2:true
-notes
| |-notesId
| |-yourdata
| |-createdBy:uidofUser //user who created note
|
-subscriptions //when onWrite() will trigger we will use this to get UID of all subscribers of creator of "note".
| |-uidofUser
| |-uidofSubscriber1:true //user subscribe to notes written. by parent node uid
| |-uidofSubscriber2:true
将 token 保存在数据库中的代码是 onTokenRefresh()
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken(); //get refreshed token
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser(); //get currentto get uid
if(user!=null){
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()); // create a reference to userUid in database
if(refreshedToken!=null) //
mDatabase.child("fcmTokens").child(refreshedToken).setValue(true); //creates a new node of user's token and set its value to true.
else
Log.i(TAG, "onTokenRefresh: token was null");
}
Log.d(tag, "Refreshed token SEND TO FIREBASE: " + refreshedToken);
}
每当为此用户创建新 token 时,上述代码将在用户的 fcmTokens 中创建新节点。
这是检索用户 token 并向这些 token 发送通知的 node.js 部分。 为此
exports.sendNotesNotification = functions.database.ref('/Notes/{pushId}')
.onWrite(event => {
const notes = event.data.val();
const createdby = notes.createdBy;
const getAllSubscribersPromise = admin.database().ref(`/subscriptions/${createdby}/`).once('value'); // retrieving subscribers
const payload = {
notification: {
username: notes.username,
title: notes.title,
body: notes.desc
}
}
return getAllSubscribersPromise.then(result => {
const userUidSnapShot = result; //results will have children having keys of subscribers uid.
if (!userUidSnapShot.hasChildren()) {
return console.log('There are no subscribed users to write notifications.');
}
console.log('There are', userUidSnapShot.numChildren(), 'users to send notifications to.');
const users = Object.keys(userUidSnapShot.val()); //fetched the keys creating array of subscribed users
var AllFollowersFCMPromises = []; //create new array of promises of TokenList for every subscribed users
for (var i = 0;i<userUidSnapShot.numChildren(); i++) {
const user=users[i];
console.log('getting promise of user uid=',user);
AllFollowersFCMPromises[i]= admin.database().ref(`/users/${user}/fcmToken/`).once('value');
}
return Promise.all(AllFollowersFCMPromises).then(results => {
var tokens = []; // here is created array of tokens now ill add all the fcm tokens of all the user and then send notification to all these.
for(var i in results){
var usersTokenSnapShot=results[i];
console.log('For user = ',i);
if(usersTokenSnapShot.exists()){
if (usersTokenSnapShot.hasChildren()) {
const t= Object.keys(usersTokenSnapShot.val()); //array of all tokens of user [n]
tokens = tokens.concat(t); //adding all tokens of user to token array
console.log('token[s] of user = ',t);
}
else{
}
}
}
console.log('final tokens = ',tokens," notification= ",payload);
return admin.messaging().sendToDevice(tokens, payload).then(response => {
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.error('Failure sending notification to uid=', tokens[index], error);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' || error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(usersTokenSnapShot.ref.child(tokens[index]).remove());
}
}
else{
console.log("notification sent",result);
}
});
return Promise.all(tokensToRemove);
});
return console.log('final tokens = ',tokens," notification= ",payload);
});
});
});
我还没有检查 node.js 部分,如果您还有问题,请告诉我。
关于Android Firebase云函数通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43712989/