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) {
}
});