Sending notifications from Firebase cloud messaging to a single device - firebase

We are building an app with chat functionality in Flutter, and I have figured out almost everything about how it should be done, except how the notifications can be sent to only one device (Or possibly a few devices).
The best option so far is to send the notification to an FCM registration token since we use Firebase for all of our back-end, but I can't do that without knowing the token. And the only way I can know that is to store it in Firestore (For example the users document) and retrieve it when needed. Is this a good solution, and what happens if the registration token changes? Should I update the token every time the user opens the app to make sure that it is correct?

You don't need to store the token on the server, you just need to know who you are sending the message to. Just follow these steps
Client
1.a When you app starts, retrieve the token via getToken()
1.b Store it locally
1.c if it has changed, send it to a Cloud function, and register it to a topic or device group
1.d Dont forget to register to onTokenRefresh() to repeat 1.a-c for new tokens
Server
2.a Implement the function corresponding to 1.c
2.b When required, send messages to a topic or device group

Related

Should I cache Firebase idTokens for a while, after I authenticated it in node admin sdk?

I am building an app, where I need to use my own backend besides Firebase. I need to authenticate a logged-in user in my backend too. So I found this tutorial which does this. I send an idToken and verify this header in admin sdk in my node, based on the docs. I thought I could cache this token with redis or just a js map after the first verification for 10 minutes or as much as a user session would take, to speed things up, instead of verifying each request in a 10 min sess. I could probably cache the token in the phone too for some time?
My question is, what security consequences would this bring? Thank you.
To clarify I am not using custom tokens, I will be using the built in Firebase Authentication.
The convention is to send the ID token to your backend with every request. It's not expensive to verify the token with the Admin SDK as shown in that documentation. It doesn't cost any money.
Typically what you're supposed to do is use a listener to detect when the ID token changes (it will be refreshed automatically every hour), and keep using that token until the SDK delivers a new one to your callback. In web clients, you're supposed to use onIdTokenChanged to register a callback to get changes to this token over time. There is no need to persist or cache this token - simply use whatever the callback most recently provided.
Some of the Firebase backend services keep a small cache of recent ID tokens, and their decoded results. So if they receive the exact same token, they'll use the already decoded result. This is a riskless operation, as the decoding operation is idempotent: the same input will always deliver the same output.

When and what Old FCM Tokens do I need to delete from my backend?

The way I understand Firebase Cloud Messaging at the moment, I will want to save all FCM tokens a user might have across devices to my backend and send a notification to all of these tokens at once when I want to notify that user about something.
Multiple tokens
Until this point, I assumed that each device only has one active token, however, reading this section of the documentation:
To enable this feature, make sure you have each sender's sender ID. When requesting registration, the client app fetches the token multiple times, each time with a different sender ID in audience field, using the token retrieval method for the given platform
Does this mean that I might need to target multiple active tokens per device?
Deletion
And now coming to the really important question. A simple solution to the above problem would be to simply store every token I ever retrieve in the backend and thus ensuring that my user will always receive the message.
However, what do I do if the user signs out of my app using Firebase Authentication, i.e. a different account is used in the same app on the same device?
I assume that the tokens I sent to my backend for this device will still be active - so now this user will receive notifications from another account because that account was signed in on the device previously.
I do have access to the current FCM token and I could delete that from my backend before signing out the old user, but considering the "Multiple tokens" section: how do I make sure that I can delete all FCM tokens of the old user from my backend?
Uniqueness
Additionally, assuming that old tokens are just dead for the device (will not trigger notifications anymore) when new ones are generated, can I be sure that this token will never be assigned to another device in the future?
TL;DR
How can I make sure that I have the correct FCM token(s) for my user stored in my backend and more importantly: how can I ensure that no tokens of other users are saved for some user in my backend?
I read through:
https://stackoverflow.com/a/40158260/6509751
However, I still do not know how to deal with multiple tokens.
Does this mean that I might need to target multiple active tokens per device?
An application has a single active token for each sender ID. It's fairly uncommon to have multiple sender ID, and you'd usually know if if you do. If you're sending from a single back-end, there's usually no need for having multiple sender IDs.

Get messaging tokens from Go admin backend when adding users to Firebase, over upon registration in Javascript

I haven't seen any examples of this, but I want to purely interact with Firebase through the backend, and not the frontend with Javascript.
I have auth tokens being minted on my Go backend when a new user is added and then these users are written into a mongo database.
What I want is to be able to get a messaging token for my users, and then add it to their user document in mongo, that'll be used to send messages through the backend.
The reasoning is that we don't want to have to communicate with Firebase on our frontend.
Is this even possible?
If you want to send a message directly to a device with Firebase Cloud Messaging, you will definitely need some information from the client. There is no avoiding following the setup instructions on the client. In particular, you will have to handle the registration token on the client and send it to your backend so it can send the messages.
The Firebase Authentication token will not be useful to you at all for sending messages. FCM doesn't send messages to users - it sends messages to devices (or topics). You will have to figure out for yourself which devices belong to which users.

How to send a push notification from the Firebase console to a specific GCM/FCM device token ID

In Urban Airship, when I am composing a notification, I can target specific users by searching for a Urban Airship channel_id (device ID):
I sent from Urban Airship the push notification that I am showing above, and I received it successfully. Now I want to do the same thing, send a push notification to a specific device, but now using the Firebase console. The problem is that in Firebase, in the step where I need to specify the target, it only allows me to choose User segment or topic. I was expecting to see a third option: Target specific users (for sending notifications to one or many specific GCM/FCM device token IDs. So my alternative is to add a GCM/FCM device token ID to a topic and then send the push notification to that topic, which is something that I have successfully done before. Nonetheless, that would be a workaround and not the way I would prefer to do this. Is it possible to send push notifications to specific users (by defining the target GCM/FCM device token IDs) from the Firebase console? Thank you.
UPDATE 1: See how the Firebase console (https://console.firebase.google.com/) only shows User segment and Topic as the Target:
First Step:
Second Step:
Third Step:
By design, the notification feature in the console is for sending out broadcast-type events. Sending user-specific alerts would be more of a programmatic operation done through the API.
For sending test messages, there is a console tool for this, explained here.
Note that it is possible to send a notification to one device by subscribing a device to any topic and sending the notification to that topic in the console (keep in mind topics are public and you can't prevent users from signing up to them; fine for testing most likely).
Another alternative is to send a message via HTTP or curl. Perhaps the best resource for this is the quickstart/messaging example.

Dynamic Push Notifications

I know that Firebase has recently added support for Push Notifications and while this is a great thing, I only seem to be able to send push notifications manually via the Notifications Panel.
What I'd like to do is to send push notifications within a user scope...Let me explain that. Each User in my App has an account and then each user can join a group. Within this group the user can perform tasks and has a list of chores to do. Now when certain tasks are due for example I want to remind the user of doing it with a push notification. For 1-10 I might be able to pull this off manually, but is there a way to dynamically based on the data in the Database send out Push Notifications?
I know that certain Push Notifications can be created using the Analytics tool such as "Hey you have not visited for 3 days, please come back whatever"... but I'd like to register push notifications such as "I just created a task, this task needs to be done within 3 days. Remind me in 3 days if the task is still not done".
Is this possible with Firebase or do I need to have my own server connecting to Firebase and handling those events?
-xCoder
You need to implement FCM in your client and in a server. Let me put this straight:
First, you need that your client, or app, to register into FCM and get a FCM token that will be used to identify that device uniquely.
Then, store that token wherever you like. It can be into firebase database or other server you may like. I recommend you to store it into firebase if you are using it as a database for your users; that's my case.
Also, you need to implement a http or xmpp server in order to send FCM messages to your registered devices containing the data you are interested in. For example, you can implement a Google App Engine endpoint (can be done with Android Studio and Java) that is quite simple or a NodeJS module, depending on your preferred language.
If you are using Firebase as database you can connect from your server with the appropriate SDK and get the FCM tokens you want from your users, and then send the message to those with data. Don't forget to secure your serve.
The way you implement your server algorithm to send FCM messages depends on your app purposes.
Hope it is clear enough for you. Also you can find all the documentation with a short video that explains the general structure here: https://firebase.google.com/docs/cloud-messaging
You can use cloud functions to trigger on any create, update or delete operation in your database and in the trigger event, you can choose to send in FCM push notifications to the devices of your choice.
Here is the documentation regarding the use and structure of a cloud function: https://firebase.google.com/docs/firestore/extend-with-functions
Hope this helps!

Resources