在不知道Firebase实时数据库中键值的情况下检索子值

时间:2019-02-21 17:55:14

标签: java android firebase firebase-realtime-database

我想获取“ drinkManufacturerID”等于currentUsers UID的父键值。但是,我将不知道VenueIDPushID的值(请参见下文)。如何在不知道这些值的情况下检查“ drinkManufacturerID”的值是否相等。是否可以不重新构造数据库?

相关代码:

public class DealRawDataActivity extends AppCompatActivity {


DatabaseReference databaseDrinks;
DatabaseReference databaseManufacturer;


String keys;

FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_deal_raw_data);


    databaseDrinks = FirebaseDatabase.getInstance().getReference("drinks").child("-LWLuM2nesg0uaP0dLSn"); //However, this string will not be know! How to get this string value?

    //To later be used in listView
    databaseDrinks.orderByChild("drinkManufacturerID").equalTo(currentFirebaseUser.getUid()).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot datas : dataSnapshot.getChildren()) {
                keys = datas.getKey();
            }
            Toast.makeText(getApplicationContext(), keys, Toast.LENGTH_LONG).show();
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

   //databaseManufacturer = FirebaseDatabase.getInstance().getReference("drinks").child(keys);

}

}

数据库结构:

enter image description here

2 个答案:

答案 0 :(得分:1)

  

我不知道VenueID或PushID的值(见下文)

您需要知道VenueID的值才能至少查询-LWLuM2nesg0uaP0dLSn节点的数据库。所以下面的查询:

.orderByChild("drinkManufacturerID").equalTo(currentFirebaseUser.getUid())

获取该特定对象内存在的所有饮料。

  

是否可以不重组数据库?

不,不幸的是,Firebase中无法按您想要的方式查询树中深处两个级别的两个或多个Firebase节点。要解决这个问题,您应该复制数据。这种做法称为denormalization,是Firebase的常见做法。如果您不熟悉NoQSL数据库,建议您观看此视频Denormalization is normal with the Firebase Database,以更好地理解。

此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。

也就是说,在您的特定情况下,您应该考虑通过创建另一个名为vanues的节点来扩展数据结构以允许反向查找,在该节点中应将所有对应的drink对象添加为对象。因此,您的数据库结构应类似于此:

Firebase-root
   |
   --- vanues
        |
        --- -LZB-86uakRrWpI6VYzd (drink object)
               |
               --- drinkManufacturerID: "D1eY ... wrT5"
               |
               --- VenueID: "-LWLuM2nesg0uaP0dLSn"

使用此架构,您只需使用以下代码行即可查询数据库以获取所有饮料,其中drinkManufacturerID等于uid

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference vanuesRef = rootRef.child("vanues");
Query query = vanuesRef.orderByChild("drinkManufacturerID").equalTo(uid);
query.addListenerForSingleValueEvent(/* ... */);

如果您想从特定的渠道获取所有饮料,只需使用:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference vanuesRef = rootRef.child("vanues");
Query query = vanuesRef.orderByChild("VenueID").equalTo(VenueID);
query.addListenerForSingleValueEvent(/* ... */);

其中VenueID可能包含-LWLuM2nesg0uaP0dLSn之类的值。

答案 1 :(得分:0)

您的代码还可以,但是它适用于uid或所有uid的所有子代。但是当您需要获得一个uid的孩子时。

我的意思是,如果UID有3个孩子,例如 UID->(Child1),(child2),(Child3)

每个孩子都有一个孩子,例如

UID->(Child1)->(childA),(childB)

......((child2)->(childC),(childD)

......((child3)->(childD),(childE)

child的这些孩子(childA,childB,childC,childD,childE)持有数据 并且您需要在不知道父密钥和子密钥的情况下获取它,那么这很容易。 您只需要这样做

for (DataSnapshot postSnapshot1 : dataSnapshot.getChildren()){for (DataSnapshot postSnapshot2 : postSnapshot1.getChildren()){//postSnapshot2 is accessed your child of child// using recycler view, adapter class and model class you can display the whole data for all child of child}}

只需将其放在您的代码上

databaseDrinks.orderByChild("drinkManufacturerID").equalTo(currentFirebaseUser.getUid()).addValueEventListener(new ValueEventListener() {
 @Override 
public void onDataChange(@NonNull DataSnapshot dataSnapshot) { 
for (DataSnapshot datas1 : dataSnapshot.getChildren()) { for(DataSnapshot datas2 : datas1.getChildren()) { String keys = datas2.getKey(); 
}} 
Toast.makeText(getApplicationContext(), keys, Toast.LENGTH_LONG).show(); 
} 
@Override public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });