How to handle push notifications for same user in more devices, more browsers - push-notification

I have an hybrid website created with Ionic on Firebase, so I have even the PWA version, an android version and an iOS version, the user can be free or authenticated.
Now I am in a problem 'cause I dont have idea how to handle the push notifications when an user could access the first time my website, then he choses to receive notification and I store on my database his/her token to send push notifications, everything ok this user has 1 token.
Now this user become registered then when he access the website I dont know this is the same user as before then I receive a new request to store a new token.
At this time this same user has 2 token in my database.
Now if the user another day will visit my website with another browser, for example firefox and accept again the notification then he has now 3 tokens on my DB.
If the same user now even install the PWA version I will get another different token and my system will store even this, now this user has 4 tokens.
Keeping going further with this examples an user could collect 6 or more tokens stored on my database.
The problem is that if now I send a notification, this user will be overhelmed by my informations and is going to receive 6 or more notifications every time I send out 1.
Which is the best way to handle this situation?

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?

How a Firebase token is generated?

I'm doing analysis on Firebase Token and understood below points:-
-> A Firebase token is saved in database which will be used for sending notifications.
-> The token generally do not expire except in the following cases:
- The app deletes Instance ID
- The app is restored on a new device
- The user uninstalls/reinstall the app
- The user clears app data.
-> When we use a token which is expired we get errors like Not Registered from the response while sending messages.
-> To avoid the error, we should be deleting the token from database.
However I have found that If we login to a cloud application (which is my app currently), a new fcm token gets generated when i logged in to a new browser say FireFox, Edge etc.
So, the token is generated based on browser or System IP or what exactly the Fcm uses to generate a token ?
The method used to generate the token is an implementation detail, and you should not depend on that to build your app.
A token uniquely identifies a device. Each device receives messages independently of each other, and does not know anything about the user of that device. It's expected that if a user signed into an app on multiple devices, that each device would generate a unique token. If you want to send message to a user, you will have to map each of the user's device tokens in your own database, and send the message to each of them, or only the ones that the user chooses.
You can expect that device tokens might change over time. If you send a message to a device, and the API tells you that the token is not valid, you should simply delete it from your records.

Push notifications by username

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.

How can I know that a Firebase Cloud Messaging token is out of use?

A single user can have multiple devices connected to his account.
Because of that he can have multiple cloud messaging tokens.
Everytime the user opens the app the token from that device is send to the app server and saved there.
What happens if a user uninstalls the app from one of his devices? I have no chance to tell the server that the token is not longer in use.
Can it occure that I notify an other user instead since this other user has acquired the not longer used token from the original user?
What happens if a user uninstalls the app from one of his devices?
Usually, when your app is uninstalled, it is advisable for you (the developer) to automatically make sure that the corresponding registration token is deleted from your own App Server.
Can it occure that I notify an other user instead since this other user has acquired the not longer used token from the original user?
No. Each registration token is unique per each app instance. So rest assured that if a registration token is invalidated/expires for whatever reason, no other user will be able to use it. Sending a message to an invalid/expired registration token will result to a NotRegistered error.
Tokens are not re-used so there should be no risk of notifying another user. Tokens cannot be acquired by one user from another.

Best practices for push notifications in multi user applications?

I'm working on a push architecture that needs to support applications which allow for multiple users. This means more than one user can log into the application with their credentials. The problem I'm running into is what if user A allows push notifications, then logs out, then user B logs in and starts getting user A's push notifications?
What are some best practices for handling this type of thing? One thought I had was you could remember the last user who logged in and only display push notifications to the "logged in" user. You would have to send some sort of user context in the message payload so it could be checked against the logged in user. However this feels a little funky.
Anyone else ran into this? It's seems like a really relevant problem, especially for tablets where families tend to share the device.
We're implementing this by Registering the device with APSN, getting the device token and sending this to our server through a ws.
On the server side the device token is only associated with the last logged in user.
New app
User A (first ever user) uses IPAD A
Register with APSN, get token
Send token to our servers through ws
Search for token in db, token is new, store it
assign token to USER A
Next user logs into app
Register with APSN, get token
Send token to our servers through ws
Search for token in db, token exists already
Remove connection to USER A
assign token to USER B
SEND Notification to device WITH USERNAME
if username is logged in show it - else dont
Still not perfect as its sent to home screen first so to ALL users
I think your suggestion is acceptable in a multi-user app. It is much simpler to implement this in the client side, than on the server side. The downside is extra bandwidth wasted to send an unneeded notification. But vast majority of the usage is probably single-user so this may not matter much.
The alternative is to track the logged on users on your server and their current reg_ids. This could be more complicated because A could be logged on on multiple devices, then logs out from device 1, and B logs onto device 1, etc. and your server has to track all of these. So probably another table to track the relationships between 'Logged On Users' to 'Reg Ids'.
If you hate the idea of sending unneeded notifications, go with the server route. If you value Keep-It-Simple principle, go with the client route.
Let's suppose users of your app can logging on multi devices.
We have to make two API on server side:
func setUserDeviceNotifyToken(userId: Int, deviceToken: String) {}
func removeUserDeviceNotifyToken(userId: Int, deviceToken: String {}
On your app side, you have to call setUserDeviceNotifyToken API on every Login In and call removeUserDeviceNotifyToken on every logout.
On server side, you can track every user with its deviceNotificationToken and send notification for correct device.
Notice: If your service doesn't suppose to support multi device login with one user, you can handle it just by one updateUserDeviceNotifyToken and pass null for remove user's device token.
Notice 2: Do not let user logout before calling removeUserDeviceNotifyToken API.

Resources