Android Firebase云端功能通知 [英] Android Firebase cloud function notification

查看:215
本文介绍了Android Firebase云端功能通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功设置了Firebase云端功能,将通知发送给主题。问题是,它发送给包括发件人在内的所有用户,我如何设置我的云功能,以便它不显示通知发件人?请帮忙?下面是如何发送到主题

  exports.sendNotesNotification = functions.database.ref('/ Notes / {pushId}') 
.onWrite(event => {
const notes = event.data.val();

const payload = {
notification:{

用户名:notes.username,
标题: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令牌将通知发送到单个设备。
用于发送FCM令牌的通知的node.js代码是

  admin.messaging()。sendToDevice(<有效载荷的数组); 

,您可以从android的FirebaseInstanceIdService的onTokenRefresh()方法获取设备标记。

  @Override 
public void onTokenRefresh(){
//获取更新的InstanceID标记。
String refreshedToken = FirebaseInstanceId.getInstance()。getToken();
//执行:将令牌发送到您的服务器或firebase数据库
}

更新:



将firebase标记存储到数据库现在您应该像这样构建数据库

  -users 
| -user1uid
| | -name //你的选择
| | -email //你的选择
| | -fcmTokens
| | -valueOftoken1:true
| | -valueOftoken2:true
-notes
| | -notesId
| | -yourdata
| | -createdBy:uidofUser //创建注释
|的用户
-subscriptions //当onWrite()触发时,我们将使用这个来获得note创建者的所有订阅者的UID。
| | -uidofUser
| | -uidofSubscriber1:true //用户订阅笔记。通过父节点uid
| | -uidofSubscriber2:true

保存数据库中的标记是 onTokenRefresh()

  @Override 
public void onTokenRefresh(){
//获取更新的InstanceID令牌。
String refreshedToken = FirebaseInstanceId.getInstance()。getToken(); //获取刷新的令牌
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser(); //获取currentto获取uid
if(user!= null){
DatabaseReference mDatabase = FirebaseDatabase.getInstance()。getReference()。child(users)。child(user.getUid()) ; //在数据库
中创建对userUid的引用if(refreshedToken!= null)//
mDatabase.child(fcmTokens)。child(refreshedToken).setValue(true); //创建用户令牌的新节点并将其值设置为true。
else
Log.i(TAG,onTokenRefresh:token was null);
}
Log.d(tag,刷新标记发送到FIREBASE:+ refreshedToken);

$ / code>

当为这个用户创建新的令牌时,上面的代码会创建新的节点在用户的fcmTokens中。

这里是检索用户令牌并向这些令牌发送通知的node.js部分。
for this

  exports.sendNotesNotification = functions.database.ref('/ Notes / {pushId}')
.onWrite(event => {

const notes = event.data.val();
const createdby = notes.createdBy;
const getAllSubscribersPromise = admin。 ()/ $ {createdby} /`).once('value'); //检索订户
$ b $ const
$ b username:notes.username,
title:notes.title,
body:notes.desc

}

} $ (!userUidSnapShot.hasChildren())返回getAllSublishersPromise.then(result => {
const userUidSnapShot = result; //结果将有孩子拥有订阅者密钥uid。
。 ){
return console.log('没有订阅用户来写通知');
}
console.log('有',userUidSnapShot.numChildren(),'用户发送通知给'。
const users = Object.keys(userUidSnapShot.val()); //获取创建订阅用户数组的关键字

var AllFollowersFCMPromises = []; //为每个订阅用户创建新的TokenList的承诺数组
for(var i = 0; i< userUidSnapShot.numChildren(); i ++){
const user = users [i];
console.log('承诺用户uid =',用户);
AllFollowersFCMPromises [i] = admin.database()。ref(`/ users / $ {user} / fcmToken /`).once('value');


return Promise.all(AllFollowersFCMPromises).then(results => {

var tokens = []; //这里是创建的令牌数组现在生病添加所有用户的所有fcm令牌,然后发送通知给所有这些。
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); //将所有用户标记添加到标记数组$ b $ console.log('token [s ]的用户=',吨);
}
其他{



$ b console.log('最终的标记=',t okens,notification =,有效载荷);
返回admin.messaging()。sendToDevice(tokens,payload).then(response => {
//对于每个消息检查是否有错误
const tokensToRemove = [] ;
response.results.forEach((result,index)=> {
const error = result.error;
if(error){
console.error('Failure发送通知给uid =',tokens [index],错误);
//清除没有注册的令牌
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(发送通知,结果);
}
});

返回Promise.all(tokensToRemove);
});

return console.log('final tokens =',tokens,notification =,payload);
});





});
});

我还没有检查node.js部分让我知道你是否还有问题。 >

I have managed to setup firebase cloud functions to send notification to topics. the problem is that it sends to all users including the sender, how can i setup my cloud function so that it doesn't show a notification to sender? please help? below is how am sending to topic

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);
            });
        }); 

解决方案

From the Docs of firebase, Using topics for sending notifications should be done for notifications that are public and are not time critical. In your case notification is not public and as sender is also subscribed to that particular topic he will also get the notification. therefore if you want to avoid sending notification to sender you have to unsubscribe that sender from your topic.

Or better solution is that you should send the notifications to single devices using there FCM tokens. the node.js code for sending notification for FCM tokens is

admin.messaging().sendToDevice(<array of tokens>, payload);

and you can get the device tokens from onTokenRefresh() method of your android's FirebaseInstanceIdService.

 @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        // TO DO: send token to your server or firebase database
}

Update:

To store the firebase tokens to your database Now you should structure your database like this

   -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

to save the tokens in database here is the code for 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);
    }

when ever new token is created for this user the above code will create new node in fcmTokens of the user.

Here comes the node.js part of retrieving users token and sending notification to those tokens. for this

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);
        });





            });
        }); 

i have not checked the node.js part let me know if you still have problem.

这篇关于Android Firebase云端功能通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆