Android Firebase cloud function notification

后端 未结 1 583

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 fun

1条回答
  •  有刺的猬
    2021-01-15 18:41

    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(, 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 {
    
                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.

    0 讨论(0)
提交回复
热议问题