根据Firebase文档中的说明,使用主题发布通知应该针对公共且不是时间关键的通知。在您的情况下,通知不是公共的,并且发送方也订阅了特定主题,因此他也会收到通知。
因此,如果您想避免将通知发送给发送方,则必须取消其订阅您的主题。
或者更好的解决方案是,使用它们的FCM令牌向单个设备发送通知。
用于发送FCM令牌通知的Node.js代码如下:
admin.messaging().sendToDevice(<array of tokens>, payload);
你可以从你的安卓 FirebaseInstanceIdService 的 onTokenRefresh() 方法中获取设备令牌。
@Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
}
更新:
现在将Firebase令牌存储到您的数据库中,您应该按照以下方式构建您的数据库结构:
-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
要将令牌保存在数据库中,这里是onTokenRefresh()
的代码:
@Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
if(user!=null){
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid());
if(refreshedToken!=null)
mDatabase.child("fcmTokens").child(refreshedToken).setValue(true);
else
Log.i(TAG, "onTokenRefresh: token was null");
}
Log.d(tag, "Refreshed token SEND TO FIREBASE: " + refreshedToken);
}
当为该用户创建新令牌时,上述代码将在用户的fcmTokens中创建新节点。
以下是检索用户令牌并向这些令牌发送通知的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');
const payload = {
notification: {
username: notes.username,
title: notes.title,
body: notes.desc
}
}
return getAllSubscribersPromise.then(result => {
const userUidSnapShot = result;
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());
var AllFollowersFCMPromises = [];
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 = [];
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());
tokens = tokens.concat(t);
console.log('token[s] of user = ',t);
}
else{
}
}
}
console.log('final tokens = ',tokens," notification= ",payload);
return admin.messaging().sendToDevice(tokens, payload).then(response => {
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.error('Failure sending notification to uid=', tokens[index], error);
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部分,请告诉我您是否仍然有问题。