使用 setIndexedQuery 获取索引数据,其中索引不是路径的结尾

Get index data with setIndexedQuery where index not end of path

我有一个 Firebase 实时数据库,其布局与此类似:

{
  "data": {
    "index_1": {
      "xxx": {
        "value_1": "Some data",
        "value_2": true
      },
    "index_2": {
      "xxx": {
        "value_1": "Some data",
        "value_2": true
      },
    "index_3": {
      "xxx": {
        "value_1": "Some data",
        "value_2": true
      },
   },
   "keys": {
     "user1": {
       "index_1": true,
       "index_2": true
     },
     "user2": {
       "index_1": true,
       "index_3": true
     }

   }
}

还有一个简单的 java class:

public class Data {
    private String value_1;
    private Boolean value_2;
    ...
    getters/setters
    ...
}

有什么(简单的)方法可以从 /data/{index}/xxx/{object} 获取对象吗?

如果布局为/data/{index}/{object},例如:

"data": {
  "index_1": {
    "value_1": "Some data",
    "value_2": true
  }
}

可以使用

keyQuery = FirebaseDatabase.getInstance()
                           .getReference("keys")
                           .orderByKey();
dataRef = FirebaseDatabase.getInstance().getReference("data");
FirebaseRecyclerOption<Data> options = new FirebaseRecyclerOptions.Builder<Data>().
        .setIndexedQuery(keyQuery, dataRef, Data.class)
        .build();

但当索引不在所需数据之前时,我还没有找到任何方法来执行此操作。

Is there any (easy) way to get objects from /data/{index}/xxx/{object}?

是的,使用以下代码行:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference dataRef = rootRef.child("data");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String value_1 = ds.child("xxx").child("value_1").getValue(String.class);
            boolean value_2 = ds.child("xxx").child("value_2").getValue(Boolean.class);
            Log.d(TAG, value_1 + " / " + value_2);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
    }
};
dataRef.addListenerForSingleValueEvent(valueEventListener);

如果你想使用 FirebaseRecyclerOption,你的数据库模式确实应该是这样的:

"data": {
  "index_1": {
    "value_1": "Some data",
    "value_2": true
  }
}

没有那个额外的 xxx child.

我找到了一种通过创建自定义 SnapshotParser 使用 FirebaseRecyclerOption 来解决它的方法

SnapshotParser<Data> parser = new SnapshotParser<Data>() {
    @NonNull
    @Override
    public Data parseSnapshot(@NonNull DataSnapshot snapshot) {
        return snapshot.child("xxx").getValue(Data.class);
    }
}
FirebaseRecyclerOption<Data> options = new FirebaseRecyclerOptions.Builder<Data>().
    .setIndexedQuery(keyQuery, dataRef, parser)
    .build();