Send push notifications using Cloud Functions for Firebase

37,793

Solution 1

I managed to make this work. Here is the code that sends a notification using Cloud Functions that worked for me.

exports.sendNewTripNotification = functions.database.ref('/{uid}/shared_trips/').onWrite(event=>{
    const uuid = event.params.uid;

    console.log('User to send notification', uuid);

    var ref = admin.database().ref(`Users/${uuid}/token`);
    return ref.once("value", function(snapshot){
         const payload = {
              notification: {
                  title: 'You have been invited to a trip.',
                  body: 'Tap here to check it out!'
              }
         };

         admin.messaging().sendToDevice(snapshot.val(), payload)

    }, function (errorObject) {
        console.log("The read failed: " + errorObject.code);
    });
})

Solution 2

Just answering the question from Jerin A Mathews... Send message using Topics:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

//Now we're going to create a function that listens to when a 'Notifications' node changes and send a notificcation
//to all devices subscribed to a topic

exports.sendNotification = functions.database.ref("Notifications/{uid}")
.onWrite(event => {
    //This will be the notification model that we push to firebase
    var request = event.data.val();

    var payload = {
        data:{
          username: request.username,
          imageUrl: request.imageUrl,
          email: request.email,
          uid: request.uid,
          text: request.text
        }
    };

    //The topic variable can be anything from a username, to a uid
    //I find this approach much better than using the refresh token
    //as you can subscribe to someone's phone number, username, or some other unique identifier
    //to communicate between

    //Now let's move onto the code, but before that, let's push this to firebase

    admin.messaging().sendToTopic(request.topic, payload)
    .then((response) => {
        console.log("Successfully sent message: ", response);
        return true;
    })
    .catch((error) => {
        console.log("Error sending message: ", error);
        return false;
    })
})
//And this is it for building notifications to multiple devices from or to one.

Solution 3

Return this function call.

return ref.on("value", function(snapshot){
        console.log("Val = " + snapshot.val());
        },
    function (errorObject) {
        console.log("The read failed: " + errorObject.code);
});

This will keep the cloud function alive until the request is complete. Learn more about returning promises form the link give by Doug in the comment.

Share:
37,793

Related videos on Youtube

Tudor Lozba
Author by

Tudor Lozba

Updated on March 27, 2021

Comments

  • Tudor Lozba
    Tudor Lozba about 3 years

    I am trying to make a cloud function that sends a push notification to a given user.

    The user makes some changes and the data is added/updated under a node in firebase database (The node represents an user id). Here i want to trigger a function that sends a push notification to the user.

    I have the following structure for the users in DB.

    Users
    
     - UID
     - - email
     - - token
    
     - UID
     - - email
     - - token
    

    Until now i have this function:

    exports.sendNewTripNotification = functions.database.ref('/{uid}/shared_trips/').onWrite(event=>{
    const uuid = event.params.uid;
    
    console.log('User to send notification', uuid);
    
    var ref = admin.database().ref('Users/{uuid}');
    ref.on("value", function(snapshot){
            console.log("Val = " + snapshot.val());
            },
        function (errorObject) {
            console.log("The read failed: " + errorObject.code);
    });
    

    When i get the callback, the snapshot.val() returns null. Any idea how to solve this? And maybe how to send the push notification afterwards?

    • Jen Person
      Jen Person almost 7 years
      Does the console.log of the uuid show the correct value?
    • Tudor Lozba
      Tudor Lozba almost 7 years
      Yes, the uuid is correct.
    • Bob Snyder
      Bob Snyder almost 7 years
      Use back-ticks to substitute the value of uuid in your ref: admin.database().ref(`Users/${uuid}`). Also you should use once() instead of on(). on() leaves the listener attached; not something you want in a cloud function.
    • Doug Stevenson
      Doug Stevenson almost 7 years
      Also, your function should return a promise that indicates to Cloud Functions when your work is done and it's safe to clean up. If you do async work without returning a promise, it will not work the way you want. It might be a good idea to go over these video tutorials to learn more: youtube.com/playlist?list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM
    • Andrew Breen
      Andrew Breen almost 7 years
      Doug is correct - with Cloud Functions you should be returning a promise so that it can watch the chain execute and then stop the instance when it is done. Because it has no way of knowing that async work is happening in this case, the function is completing before the async work is actually completed.
  • Tudor Lozba
    Tudor Lozba almost 7 years
    Thank you all for your answers. Combining them helped me to achieve what i wanted!
  • Aawaz Gyawali
    Aawaz Gyawali almost 7 years
    Its my pleasure, please accept the answer if it helped your problem. @TudorLozba
  • Jerin A Mathews
    Jerin A Mathews over 6 years
    is there any way to send messages to a topic using firebase cloud function?
  • Deepak Gautam
    Deepak Gautam over 5 years
    will this code send notification to all the users? What if I wants to send notification to only one user like whatsapp message notification.
  • Codelicious
    Codelicious over 5 years
    @DeepakGautam This will only send to one specific device. Note sendToDevice is a legacy method. See firebase.google.com/docs/cloud-messaging/admin/send-messages
  • Joseph Wambura
    Joseph Wambura about 5 years
    Hello, what if I have a specific topic I want to send to? Say, like some people subscribed to GoodMorning topic and another group NoonTopic. Kindly assist.
  • Arjun
    Arjun almost 5 years
    I'm using the above cloud function to send notification, but I don't know how to receive for iOS. Could somebody please let me know how to receive the above notification and display its content to the user?
  • DevAS
    DevAS almost 5 years
    @Gsilveira can you check this,stackoverflow.com/questions/56656303/…