Bargain23
Bargain23

Reputation: 1973

Firebase database - how do I ensure uniqueness of values before pushing to database if each value has a randomly generated key

I'm using the Android SDK to write device tokens to my Firebase database. I am associating these tokens to users. I am assuming that each user may have one or more devices. Hence, this is what my current database structure looks like:

{
  "users" : {
    "1" : {
      "-LAwu8VKATAxifCOZIPn" : "Device_Token_For_User_1",
      "-LAwyfXcoLcXBX3rOshb" : "Device_Token_For_User_1"
    },
    "8" : {
      "-LAwuR9cel-p0kXv-LCn" : "Device_Token_For_User_8"
    }
  }
}

As you can see, User 1 (represented by the key "1") contains the same token that was written twice but with different keys (left side). These keys are generated randomly because of the push() method. I actually only care about the values themselves, but I want to avoid writing the same token to a particular user more than once.

I push the tokens into my database into the Firebase database this way:

String token = FirebaseInstanceId.getInstance().getToken();
Person currentUser;
try {
    currentUser = Reservoir.get("current_user", Person.class);
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference();
    myRef.child("users").child(Integer.toString(currentUser.id)).push().setValue(token);
} catch (IOException e) {
    Log.e("ERROR", "Cannot fetch user from reservoir.");
    Toast.makeText(getApplicationContext(), "An unexpected error occurred.", Toast.LENGTH_SHORT).show();
    e.printStackTrace();
}

All is well, except that when a user logs out and logs in back to the same device, the same token will be pushed twice to the database, which is what happened to User 1.

Upvotes: 0

Views: 101

Answers (2)

André Kool
André Kool

Reputation: 4978

Instead of using the token as the value you could use it as the key, to ensure it will be unique, and give it an arbitrary value like true.

You would have to change your code like this:

myRef.child("users").child(Integer.toString(currentUser.id)).child(token).setValue(true);

This will result in the following database:

{
  "users" : {
    "1" : {
      "Device_Token_For_User_1" : true,
      "SecondDevice_Token_For_User_1" : true
    },
    "8" : {
      "Device_Token_For_User_8" : true
    }
  }
}

Upvotes: 1

Peter Haddad
Peter Haddad

Reputation: 80914

It is better to use the userido, then you can check if the token exists in the database, if it does not exist then you you can add it to the database.

String token = FirebaseInstanceId.getInstance().getToken();
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference();
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();

myRef.orderByChild(user.getUid()).equalTo(token).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(!dataSnapshot.exists()){
               myRef.child("users").child(user.getUid()).setValue(token);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

Upvotes: 0

Related Questions