android - 如何根据 Firebase 实时数据库中的“设备”子项在 RecyclerView 中显示数据“用户设备”设备名称
问题描述
这是我的示例 Firebase 实时数据库
{
"devices": {
"123456": {
"device_mac_id": "123456",
"device_name": "BOX 12",
"id": "2"
},
"222222": {
"device_mac_id": "222222",
"device_name": "BOX 22",
"id": "3"
},
"888888": {
"device_mac_id": "888888",
"device_name": "BOX 88",
"id": "6"
}
},
"users": {
"UcI1REoXAoSC7mg4u7RGbw8gR2g2": {
"email_id": "ab@cd.com",
"full_name": "Ab Cd",
"id": "UcI1REoXAoSC7mg4u7RGbw8gR2g2",
"user_devices": {
"-MIbRGtT25ki36foJ6b5": "888888",
"-MIc-ORsWRqO45OJrBXg": "123456"
}
}
}
}
仪表板片段.java
{
showProgressBar();
deviceModelArrayList.clear();
devicesAdapter.notifyDataSetChanged();
mDatabaseRef
.child("users")
.child(FirebaseAuth.getInstance().getUid())
.child("user_devices")
.orderByKey()
.addChildEventListener(
new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
Log.e(TAG,
"onChildAdded:"
+ " snapshot:" + snapshot.getValue()
+ " previousChildName:" + previousChildName);
getDeviceData(snapshot.getValue(String.class));
}
@Override
public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
Log.e(TAG,
"onChildChanged:"
+ " snapshot:" + snapshot.getValue()
+ " previousChildName:" + previousChildName);
}
@Override
public void onChildRemoved(@NonNull DataSnapshot snapshot) {
Log.e(TAG,
"onChildRemoved:"
+ " snapshot:" + snapshot.getValue());
}
@Override
public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
Log.e(TAG,
"onChildMoved:"
+ " snapshot:" + snapshot.getValue()
+ " previousChildName:" + previousChildName);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Log.e(TAG,
"onCancelled:"
+ " error:" + error.toString());
}
});
}
private void getDeviceData(String deviceID) {
if (deviceID != null) {
mDatabaseRef
.child("devices")
.child(deviceID)
.addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
hideProgressBar();
// This method is called once with the initial value and again
// whenever data at this location is updated.
UserModel.DeviceModel deviceModel = dataSnapshot.getValue(UserModel.DeviceModel.class);
Log.e(TAG, "onDataChange: devices: " + deviceModel.getDevice_name());
deviceModelArrayList.add(deviceModel);
devicesAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError error) {
hideProgressBar();
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
}
);
}
}
我想在 RecyclerView 中显示,但数据随着 onDataChanged 不断增加,我正在将对象添加到 ArrayList。如果我错了或最佳实践,请建议我。
解决方案
根据您的最后评论:
是的,有 3 台设备,但我只为用户分配了 2 台。
要获取DeviceModel
仅与特定用户对应的对象,您需要使用该方法两次遍历 DataSnapshot 对象getChildren()
,如以下代码行所示:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userDevicesRef = rootRef.child("users").child(uid).child("user_devices");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot userDeviceSnapshot : dataSnapshot.getChildren()) {
String deviceId = userDeviceSnapshot.getValue(String.class);
DatabaseReference userDevicesRef = rootRef.child("devices").child(deviceId);
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot deviceSnapshot) {
UserModel.DeviceModel deviceModel = dataSnapshot.getValue(UserModel.DeviceModel.class);
Log.d("TAG", deviceModel.getDevice_name());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
userDevicesRef.addListenerForSingleValueEvent(eventListener);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
userDevicesRef.addListenerForSingleValueEvent(valueEventListener);
logcat 中的结果将是:
BOX 88
BOX 12
但这只是为了看到它正在起作用。在您的情况下,您应该将这些对象添加到列表中并通知适配器有关更改。