Android Firebase云函数通知

标签 android firebase push-notification google-cloud-functions

我已经成功设置了 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/

相关文章:

firebase - 如何在 Firebase Firestore Collection 中构造版本化数据?

java - 时间推送通知java

android - Google C2D_MESSAGE 应用程序未定义权限?

java - token "}"上的类型语法错误,删除此 token

android - 当应用是应用商店时从android获取日志

android - Retrofit2 请求Body前面不同括号的奇怪组合

android - 实现滚动抽屉导航的最佳方式

java - Android 与 SDK 版本同步问题

javascript - 如何将函数外部的变量传递给 firebase 事件

macos - 选项卡关闭时不显示 Web 推送通知