30

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?

5
  • Does the console.log of the uuid show the correct value? Commented Jun 14, 2017 at 14:39
  • Yes, the uuid is correct. Commented Jun 14, 2017 at 14:54
  • 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. Commented Jun 14, 2017 at 15:23
  • 2
    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 Commented Jun 14, 2017 at 17:35
  • 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. Commented Jun 15, 2017 at 7:58

5 Answers 5

40

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);
    });
})
Sign up to request clarification or add additional context in comments.

4 Comments

is there any way to send messages to a topic using firebase cloud function?
will this code send notification to all the users? What if I wants to send notification to only one user like whatsapp message notification.
@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
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?
9

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.

2 Comments

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.
@Gsilveira can you check this,stackoverflow.com/questions/56656303/…
1

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.

2 Comments

Thank you all for your answers. Combining them helped me to achieve what i wanted!
Its my pleasure, please accept the answer if it helped your problem. @TudorLozba
1

Send Notification for a Topic In Cloud function

Topics a basically groups you can send notification for the selected group

    var topic = 'NOTIFICATION_TOPIC';
    const payload = {
        notification: {
            title: 'Send through Topic',
            body: 'Tap here to check it out!'
        }
   };

   admin.messaging().sendToTopic(topic,payload);

You can register the device for any new or existing topic from mobile side

2 Comments

Thanks this worked great! How can I modify it? Sound, badge etc.
0
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);


exports.sendNotificationToTopic = 
functions.firestore.document('Users/{uuid}').onWrite(async (event) => {

//let title = event.after.get('item_name');
//let content = event.after.get('cust_name');
var message = {
    notification: {
        title: "TGC - New Order Recieved",
        body: "A New Order Recieved on TGC App",
    },
    topic: 'orders_comming',
};

let response = await admin.messaging().send(message);
console.log(response);
});

For sending notifications to a topic, The above code works well for me, if you have any doubt, let me know.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.