Firebase数据库 - 如果每个值都有一个随机生成的密钥,如何在推送到数据库之前确保值的唯一性

时间:2018-04-25 13:35:23

标签: android firebase firebase-realtime-database

我使用Android SDK将设备令牌写入我的Firebase数据库。我正在将这些令牌与用户关联起来。我假设每个用户可能有一个或多个设备。因此,这就是我当前的数据库结构:

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

正如您所看到的,用户1(由键" 1"表示)包含两次写入但具有不同键(左侧)的相同令牌。由于push()方法,这些键是随机生成的。我实际上只关心值本身,但我想避免多次向特定用户写入相同的令牌。

我将令牌以这种方式将我的数据库推入Firebase数据库:

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

一切都很好,除了当用户注销并登录到同一设备时,相同的令牌将被推送到数据库两次,这就是用户1所发生的事情。

2 个答案:

答案 0 :(得分:1)

不是使用令牌作为值,而是将其用作键,以确保它是唯一的,并为其赋予任意值,如true。

您必须像这样更改代码:

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

这将产生以下数据库:

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

答案 1 :(得分:0)

最好使用userido,然后你可以检查数据库中是否存在令牌,如果它不存在,那么你可以将它添加到数据库中。

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

        }
    });