1

I'm developing a push notification app, do you have same issue:

My app generate a FCM device token and store it in a cloud database, so I can send notification messages to a device via FCM, and my database table looks like:

userid | device_token

Mary | xxxxxxxxxxxxxxxxxxxxxxxxxxxx // token1, from Mary's first device

John | yyyyyyyyyyyyyyyyyyyyyyyyyyyy

Mary | zzzzzzzzzzzzzzzzzzzzzzzzzzzz // token2, from Mary's second device Mary | kkkkkkkkkkkkkkkkkkkkkkkkkkkk // token, from Mary's first device .......

After Mary reinstalled this app from her first device, a new device token generated, and it is stored with token3.

How can I remove the expired device token token1, the only information I got may only be a pair of device token and an account name.

So how do you manage your device in this situation?

Shawn Lee
  • 103
  • 2
  • 8

2 Answers2

2

If "Mary" is using the same account to log in each time in your app, even if it is a new phone or reinstalled app why do you create a new token field inside the database? Why don't you always write inside the same token field so you always have access to this field. This will also send notifications only to the phone that your user is actually using right now. So each time when the user starts the app check token, if not equal write the new one inside your database. And from the server-side take those tokens and send notifications.

Am I missing something?


To do this, I would suggest using FirebaseAuth for the SignIn and SignUp process of your application. Then use generated uid as the field ID for the user inside the Realtime Database. You can get this uid with FirebaseAuth.getInstance().getCurrentUser().getUid(). So your user Mary will always have the same uid no matter what phone she uses. Always find the user inside the database with this uid and overwrite the existing Firebase token. This also means that your "users" will not be a single line field inside the database, but a more complex and better representation of a user. You can use model classes for this like:

public class User {

    public long id = 0;
    public long account_id = 0;
    public String account_name = "";
    public String first_name = "";
    public String last_name = "";
    public String email_address = "";
    public String password = "";

    public User() {

    }

}

It's up to you on how to configure this. But using models is also helping you on posting and retrieving data, like this:

Creating new user:

DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(user);

Retrieving data from the real-time database:

DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference databaseUsers = database.child("users");
User myUser = null;
Query usersQuery = databaseUsers.orderByChild("username").equalTo(uid); //you can use any value to order as you want, or you don't have to, there is many options for this query
usersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
     @Override
     public void onDataChanged(@NonNull DataSnapshot snapshot) {
         try {
             for (DataSnapshot user : snapshot.getChildren()) {
                 myUser = user.getValue(User.class);
             }
         } catch (Exception e) {
             e.printStackTrace();
      }
      @Override
      public void onCancelled(@NonNull DatabaseError error) {
      }
});
SlothCoding
  • 1,546
  • 7
  • 14
  • thans for your reply, but the device token is generated by FCM, and if the app is reinstalled, removed the device token will change, I have no idea to handle these tokens, and I don't know how to check if these tokens have expired or not. All devices that "Mary" logged in should receive notifications at the same time like Whatsapp did. So that's why I need to store a new token everytime Mary logged on different device. any ideas for this? BTW,thanks for the FirebaseAuth code sharing. – Shawn Lee Feb 03 '21 at 09:11
  • Not sure why would you want to send notifications to every device that Mary is using. If you want that then you can store those tokens in a List under Mary's profile in your database. Each time a user signs in you can get that token, check this: https://firebase.google.com/docs/auth/admin/verify-id-tokens#retrieve_id_tokens_on_clients ..... But I would recommend not to do that and use only the latest token you got. Depends on the app really. But if she removed an app and you still sending a notification to that token which is now invalid, why would you want that? – SlothCoding Feb 03 '21 at 09:15
  • Thanks a lot! In my case I have to notify every devices that Mary is currently using. I already got a work around from here: https://stackoverflow.com/questions/42247765/firebase-cloud-messaging-managing-registration-tokens/42248240#42248240 – Shawn Lee Feb 03 '21 at 10:00
  • No problem, paste your solution or accept my answer as helpful for future users to see. I am glad I could help you, happy coding! If anything else you need, just comment here. – SlothCoding Feb 03 '21 at 10:03
0

Inspired by this: Firebase Cloud Messaging - Managing Registration Tokens

When a token generated: if Mary logged in:

  1. add the device to the "Mary" Device Group.
  2. store the device group id and connect the device group id to "Mary"'s profile in database.

if app server need to send notification to Mary, just send to the Device Group, the benifit is that you don't need to check if the device token is valid or not, Firebase Cloud Messaging discards invalid device tokens.

if no one logged in: do nothing or just store the device token.

Shawn Lee
  • 103
  • 2
  • 8