Push notifications by username - push-notification

I have been looking for ways to send notifications to specific users and what I found was that I need the device token to do that.
I have tried Firebase and Ionic Cloud Service to do some pushs and it worked fine, but I'm wondering if it's possible to register a service with a key -> value, for exemple, register with the username and the token. If so, how can I do it?
And what is the best service to do it?
Thank you in advance for the help.
P.S.: I'm not asking for code, just the theory.

From you question [for example, register with the username and the token. If so, how can I do it?] I understand following.
You mean to say, there is a mobile app, which user will sign up to use and you want to send the notification to registered user i.e. get send push notification by username.
To solve this, you can follow the steps mentioned below.
On app launch when you get FCM registration token, save it to some intermediate location such as local storages along with device-id, mobile details etc..
Create a backend API which can save username and registration token in DB.
When a user signs up or signs in, then fetch the registration token from local storages, post username, token to backend API to save it. You can make backend API bit intelligent to handle multiple devices of the single user, distinguishable by device-id, mobile details.
Then while sending API from the backend, you can fetch all registration ids of a single user and send the notification to that users using all tokens of that user in FCM API. Use registration ids as JSON array in "registration_id" field. FCM Document - link.

Related

What does firebase use to generate a registration token?

I have already created a push notification system using firebase. It generates and saves a token for a user, then upon login displays their subscription status. It works fine, unfortunately it’s only one device per user, the most recent device they logged in on. I’d like to allow for multiple devices per user.
I’m assuming firebase uses some ID unique to each device to generate a token. If I’m wrong in that assumption, please point me in the right direction.
As Doug commented, since FCM doesn't associate its tokens with users, this is probably some limitation in your implementation.
You'll want to allow multiple ID tokens per user in your database, and then send to all tokens for the current user. If the device/app install can be shared between users, you'll want to remove the association between the user and the token for that installation when the user signs out/a new user signs in.
On associating tokens with users, see:
Is FCM (firebase cloud messaging) Token for one device or for one account?
When to register an FCM token for a user
How to get Firebase user id from FCM token? (in admin code on server)
And then finally you'll also want to clean up any tokens that FCM flags as not valid anymore, as otherwise you'll keep adding more and more tokens, which may not be valid anymore.
On deleting expired tokens, see:
When device token expires, is it automatically removed from FCM device group?
How do I identify and delete the expired FCM token on server?

FCM Token - When should I store/save it on my DB?

I am not sure what a proper FCM token handling mechanism would be so I’m writing our process down here just to get some validation or suggestions for improvements:
Fetch FCM token on client Login (Flutter)
Save FCM token on our Database (Using our REST API)
Delete FCM token on Logout (Using our REST API)
Q1: Should we be getting the FCM token more often than just on login? AFAIK, FCM token only changes on app re-installs, clearing cache, etc. Does this also include app-updates from the PlayStore? In that case, should we save the FCM token on every app launch since the user will remain logged in after an app update and hence we wouldn't trigger the save FCM call.
Q2: Did I mention the right way to handle deleting FCM tokens from our DB? We don’t want the user to keep getting notifications once they have logged out.
Q3: An add-on idea is to send the device_id to the server along with the fcm_token so that server deletes all previously saved FCM tokens for that device_id. This is useful to not have useless tokens on the DB from cases where the user uninstalls the app without logging out (which means that the DELETE fcm_token call never went through.)
The FCM token is refreshed under conditions that you don't control, and those conditions have even changed over time. To handle token updates properly, you'll need to implement both initially getting the token and then monitoring for token updates.
Note that FCM tokens are not associated with a user. It is fine if you want to associate them with a user, but it's up to your application code in that case to maintain the association. So that for example includes deleting the token from your database when the user signs out, as you're doing in step 3. 👍
For keeping your token registry clean, you can indeed do this proactively as you intend, or reactively as shown here: https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js#L76-L88
Hi Rohan fundamentaly you should use below logic to save tokens on server.
Step1:
as soon as you get token in callback whether new or same try to save it localstorage.
Step2:
Call your REST API to save it to your server. it is upto you if you want to send unique user identifier along with the token.
Step3:
It is obvious you will recieve token callback a lot of time so you can check whether you have similar token in localstorage, it means you have the token on the server so no point calling REST API.
Step 4: Now your app can send events back to server and based on it trigger Push notifications to the users.
Step 5: You can Add/update user token based on uniqye user identifier. In some cases a user can be guest user, so your app should generate guest userId and link it with token.
Stay safe.

Keeping emails synchronized between Firebase auth and database

I am using Firebase Web for a SaaS solution. My purpose is to have access to users' email at any time, either for sending notifications or triggering alerts from the backend.
For security reasons, Firebase auth does not allow to list users' email or to fetch emails based on user IDs. As a consequence, I keep a copy of the email into a specific collection in the Firebase database when a user account is created. The copy is made by a Cloud function that is triggered on user creation (following guidelines: https://firebase.google.com/docs/auth/extend-with-functions).
Thanks to the copy available in the Firebase database, I can access users' email. However, my issue is when a user changes his email.
Firebase auth provides the updateEmail function that returns a promise. I use this last to update the email in Firebase auth. Then, when the promise resolves I update the user email in the Firebase database. However, this has a major drawback: all the logic is performed on the client side and since both operations are not performed in a transaction if the client refreshes or closes his browser (or assume it crashes), then it is possible that Firebase auth is updated but not the Firebase database, thus leading to an inconsistent state.
I looked at the documentation, expecting the possibility to trigger a Cloud function when user auth information is updated. Unfortunately, I cannot find such a feature.
Another solution I thought about is to update the database from the Web client. Then, this last triggers a Cloud function that updates Firebase auth with the admin SDK. This last solution works but bypasses the check performed by updateEmail that ensures the new email is not used by another account. Also, the account hijacking protection performed by updateEmail is evicted, which is really bad from a security point of view.
Any idea to solve this problem properly is welcome.
Here are a couple of options:
When calling updateEmail, update the email in your database first before calling updateEmail. THowever, if an error occurs, you need to catch it and undo that change in your db.
When a user wants to updateEmail, send their id token and new email to your server or firebase function http endpoint. There you verify the ID token with the admin SDK, then use the client SDK require('firebase'), using the uid from the ID token, admin.auth().createCustomToken(uid), then using client SDK, firebase.auth().signInWithCustomToken(customToken). You can then call user.updateEmail(newEmail) on the backend and save the email.
Always save the uid only and just use Admin SDK admin.auth().getUser(uid) to look up the user and get their email. This guarantees you get the user's latest email as you will not be able to catch the email revocation if the user chooses to do so.
No need to save anything. Use the CLI SDK to download all your users and their emails. Check https://firebase.google.com/docs/cli/auth#authexport
This is also better as you will always be able to get the latest email per user even if they revoke the email change.

Can I access the registration tokens of all users registered in my Firebase notifications?

Sometimes I want to send a message through Firebase notifications to one unique user, then I want access the token from that user, so I like to know what is the best practice for get that token at any time?
On initial startup of my app, the FCM SDK generates a registration token for the client app instance.
I can get that token, but if I save that token in Firebase realtime database, I think other people can access that data because it is "set persistent mode on" to access offline data.
My questions is:
Is it possible to get tokens of all users without save that in a database?
Can I get these tokens direct from Firebase Authentication? If not, what is the best practice for access these tokens?
I think other people can access that data because it is "set persistent mode on" to access offline data.
Simply save the registration token details to a secure node. Making sure that only you (or even including the user itself) to be the only ones that can access it. Read more on Understand Firebase Realtime Database Rules.
I can get that token, but if I save that token in Firebase realtime database, I think other people can access that data because it is "set persistent mode on" to access offline data.
Users won't be able to get the data they're not allowed to/wasn't designed to have on their device if you choose to restrict them.
Is it possible to get tokens of all users without save that in a database?
There is no API to get all the registration tokens related to your app. As mentioned in the documentation (emphasis mine):
After you've obtained the token, you can send it to your app server and store it using your preferred method. See the Instance ID API reference for full detail on the API.
It's the developer's (you) responsibility to send and store the registration token to a secure location.
Can I get these tokens direct from Firebase Authentication?
I'm not entirely sure what you mean by this. FCM Registration tokens are different from auth tokens. So, no.
If not, what is the best practice for access these tokens?
So long as you store the tokens in a secure location and make sure that you're always using the most recent/valid token, it should be good.

How to update data from device via REST to Firebase

I have been working on a problem, where I want to update the value on Firebase Real-time Database.
I am unable to understand is there any way where I can validate my HTTPS request by my custom AUTH key? As I don't want the device to get the auth token from user authentication.
Thanks in advance.

Resources