1
votes

I'm having issues in retrieving a token saved in realtime database using cloud function's admin.database(). There is only one token to read from the child.

Firebase Database structure

enter image description here

Here's my code in Index.js

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

exports.sendNotification = functions.database
.ref('/Logs/{LogsID}')
.onWrite( (change, context) => {
    const notificationSnapshot = change.after.val();
    const status = notificationSnapshot.Status;
    const time = notificationSnapshot.Time;
    const payload = {
        notification: {
            title : status,
            body : time
        }
    }
    console.info(notificationSnapshot);
    const pushToken = admin.database().ref('/Tokens').once('child_added').then( (data) => {
        const tokenSnapshot = data.val();
        const finaltoken = tokenSnapshot.token;
        console.info(finaltoken);
    })

// Need help down here.

    admin.messaging().sendToDevice(finaltoken, payload)
    .then( () => {
        console.log('Notification sent');
    })
    .catch( () =>{
        console.log('Notification failed');
    })
    return null;
});

finalToken shows the correct token in log as expected. Log Showing the token

But I'm getting error while I'm passing the same token to admin.messaging(). Console is logging 'Notification sent' but not receiving a notification.

ReferenceError: finaltoken is not defined at exports.sendNotification.functions.database.ref.onWrite (/user_code/index.js:43:36) at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:105:23) at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:135:20) at /var/tmp/worker/worker.js:827:24 at process._tickDomainCallback (internal/process/next_tick.js:135:7)

It works when I directly pass the token like,

var finalToken = 'ephrj1........kndji'

so the admin.messaging() works, only passing the token is not working.

I'm new to Cloud Functions and javascript, so any help is much appreciated.

1

1 Answers

0
votes

Final token is being retrieved in callback / async function.

That means that when you add it to .sendToDevice() the token is undefined because the async function has not retrieved the token from the database... yet.

const pushToken = admin.database().ref('/Tokens').once('child_added').then( (data) => {
        const tokenSnapshot = data.val();
        const finaltoken = tokenSnapshot.token;
        console.info(finaltoken);

        admin.messaging().sendToDevice(finaltoken, payload)
        .then( () => {
          console.log('Notification sent');
        })
        .catch( () =>{
          console.log('Notification failed');
        })

       // I moved admin.messaging above this bracket
  })

// It used to be here

return null;

Try putting the admin.messaging code within the code block of (data) => {}

By doing this we ensure that whenever we call sendToDevice() the token is defined.