4

I'm working towards implementing push notifications that appear on change to a firebase firestore document. I'm using the react-native-firebase module. My google cloud function listens for changes to the firestore and then sends messages via firebase-admin.

google's reference says you can specify a single device to message with:

// This registration token comes from the client FCM SDKs.
var registrationToken = 'YOUR_REGISTRATION_TOKEN';

var message = {
  data: {
    score: '850',
    time: '2:45'
  },
  token: registrationToken
};

// Send a message to the device corresponding to the provided
// registration token.
admin.messaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

client-side in my react-native app I get a token using react-native-firebase:

function getToken() {
  let fcmToken = await AsyncStorage.getItem("fcmToken");
  if (!fcmToken) {
    fcmToken = await firebase.messaging().getToken();
    if (fcmToken) {
      await AsyncStorage.setItem("fcmToken", fcmToken);
    }
  }
}

Do I have to store the google cloud messaging token somewhere other than async storage or is there a way to access it as is, inside my google cloud function? It seems like I should be storing the auth token inside firestore and accessing firestore with cloud functions. is this the best way to do this?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Jim
  • 1,988
  • 6
  • 34
  • 68

1 Answers1

4

You don't need AsyncStorage to access the token, it is available right from fcmToken = await firebase.messaging().getToken(); in your code.

From there you can either send it to a callback Cloud Function with something like:

var sendMessage = firebase.functions().httpsCallable('sendMessage');
addMessage({ token: fcmToken }).then(function(result) {
  // ...
});

This is based on the example in the documentation here. You can then use this value in your Cloud Functions code to send a message by calling the FCM API through the Admin SDK.

Or store it in a database, such as Cloud Firestore with something like this:

db.collection("tokens").add(docData).then(function() {
    console.log("Token successfully written to database!");
});

Which is based on the example in the documentation here. You can then read this value from the database in your Cloud Function and use it to again send a message by calling the FCM API through the Admin SDK.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 2
    The device token is sent automatically with callable functions. https://firebase.google.com/docs/reference/functions/providers_https_.callablecontext.html#instanceidtoken – Doug Stevenson Oct 29 '19 at 00:54
  • 2
    Oooh cool. I didn't know that. :) Even easier in that case, you can get the instance ID token in your callable Cloud Function from `context.instanceIdToken`. – Frank van Puffelen Oct 29 '19 at 01:15
  • Note that in your client app if you saved your new user after authenticating then when you run `firestore().collection(users).doc(uid).get()` the raw response object includes the fcmToken so you can write it to your database and then get it in your cloud function using the users id, here is an example: https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js –  Dec 23 '20 at 06:42