簡體   English   中英

如何在 android 工作室中的 firebase 數據庫中讀取子節點而不提及父節點?

[英]How to read child nodes without mentioning parent node in firebase database within android studio?

我正在使用 firebase 實時數據庫制作 android 應用程序。 我的規則結構如下:

{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data

  "rules": {
    "Users": {
      "$uid": {
        ".read": true,
        // or ".read": "auth.uid != null" for only authenticated users
        ".write": "auth.uid == $uid"
      }
    }
  }
}

這意味着用戶應該以經過身份驗證的用戶身份登錄才能寫入一些數據。 但是在閱讀時不需要登錄。

現在我需要忽略用戶的uid以免費訪問其他用戶(即無需登錄)。 在此處輸入圖像描述

這是我目前用來讀取數據的 java 代碼。

final Intent k = getIntent();
        final String school = Objects.requireNonNull(k.getExtras()).getString("School");
        final Intent i = getIntent();
        final String roll = Objects.requireNonNull(i.getExtras()).getString("Roll");
 myRef = myfire.getReference("Users")
.child("GcZoeK7JIbNWVOog6ZjUPiBfxwn2")// **I have problem here.**
.child(school).child(roll);
        myRef.child("basic").addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                String name = (String) dataSnapshot.child("fb01name").getValue().toString();

                String number = (String) dataSnapshot.child("fb04roll").getValue().toString();

                if(name == null){

                    Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
                }

                basic model = new basic(name,number);
                tvName.setText(name);

                tvRoll.setText(number);



            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }

        });

我無法決定寫什么而不是第一個孩子在沒有登錄的情況下讀取任何數據。

.child("GcZoeK7JIbNWVOog6ZjUPiBfxwn2")

請指導我如何忽略這個孩子? 任何幫助將不勝感激。

編輯@Abdullah Z Khan 的“盡量避免使用深度嵌套的孩子”的建議進一步讓我深入了解了這個問題。 我更改了我的代碼,如下所示:

 myfire = FirebaseDatabase.getInstance();
        final Intent k = getIntent();
        final String school = Objects.requireNonNull(k.getExtras()).getString("School");
        final Intent i = getIntent();
        final String roll = Objects.requireNonNull(i.getExtras()).getString("Roll");
        
//--------------------the trick----------------

        if (school.equals("224613")){
             tvSchool.setText("GcZoeK7JIbNWVOog6ZjUPiBfxwn2");
        }else if (school.equals("224614")){
             tvSchool.setText("uQx5jDVRp9PV3QpM2FBU6HPq5SJ3");
        }
        final String uid = tvSchool.getText().toString();
//---------------------------------------------------
        myRef = myfire.getReference("Users").child(uid).child(roll);
        myRef.child("basic").addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                String name = (String) dataSnapshot.child("fb01name").getValue().toString();

                String number = (String) dataSnapshot.child("fb04roll").getValue().toString();

                if(name == null){

                    Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
                }

                basic model = new basic(name,number);
                tvName.setText(name);

                tvRoll.setText(number);



            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }

        });

雖然這個PLAN B暫時讓我松了口氣,但問題仍然沒有得到解答。因為每次加入應用程序時我都必須編寫用戶的uid代碼(並且必須一次又一次地更新和發布應用程序。更好的解決方案是等待着。

編輯:>>>標記行中添加值以供理解

從給出的內容來看,這是您的數據庫結構:

{
    "uid": {
        "schoolId": {
            "roll": {

            }
        }
    }
}

因為它是如此嵌套(我建議完全不同的層次結構),所以沒有簡單的方法可以按原樣訪問具有未知父級的子級。 但是,如果您可以將數據庫結構更改為:

{
    >>> "224614":"GcZoeK7JIbNWVOog6ZjUPiBfxwn2",
    "schoolId2":"uid2",
    >>> "GcZoeK7JIbNWVOog6ZjUPiBfxwn2": {
        "224614": {
            "roll": {

            }
        }
    }
}

您將獲得一個 uid 查找表。 然后,您可以使用它來到達節點。 請記住,這不是您所問問題的直接答案,即如何在不知道父級的情況下獲取嵌套節點(不是值),但在這里您可以動態訪問所需學校的 uid,假設每所學校都有一位家長。

之后,嵌套你的監聽器:

myRef = myfire.getReference("Users");
myRef.child(school).addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if  (dataSnapshot.exists()) {
                    String uid=dataSnapshot.getValue(String.class);
                    myRef.child(uid)// **I have problem here.**
                    .child(school).child(roll);
                            myRef.child("basic").addValueEventListener(new ValueEventListener() {

                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                    String name = (String) dataSnapshot.child("fb01name").getValue().toString();

                                    String number = (String) dataSnapshot.child("fb04roll").getValue().toString();

                                    if(name == null){

                                        Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
                                    }

                                    basic model = new basic(name,number);
                                    tvName.setText(name);

                                    tvRoll.setText(number);



                                }

                                @Override
                                public void onCancelled(@NonNull DatabaseError error) {

                                }

                            });
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }

        });

在實踐中,盡量避免使用深度嵌套的子節點,而是使用對其他節點的引用。

我希望這有幫助!!

這個怎么樣:

final Intent k = getIntent();
    final String school = Objects.requireNonNull(k.getExtras()).getString("School");
    final Intent i = getIntent();
    final String roll = Objects.requireNonNull(i.getExtras()).getString("Roll");
    myRef = myfire.getReference("Users")
    
    myRef.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            String name = (String) dataSnapshot.child(school).child(roll).child("basic").child("fb01name").getValue().toString();

            String number = (String) dataSnapshot.child(school).child(roll).child("basic").child("fb04roll").getValue().toString();

            if(name == null){

                Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
            }

            basic model = new basic(name,number);
            tvName.setText(name);

            tvRoll.setText(number);



        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }

    });

好吧,我不知道我是否理解你的問題,但是如果你試圖讀取所有節點的子節點而不指定它們,你可以嘗試執行下面的代碼:(我沒有測試它,我剛剛改變了你的樣本)

    myRef = myfire.getReference("Users");
    myRef.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            for (DataSnapshot keySnap : dataSnapshot.getChildren()) {
                for (DataSnapshot schoolSnap : keySnap.getChildren()) {
                    for (DataSnapshot rollSnap : schoolSnap.getChildren()) {
                        String mRollSnap = rollSnap.getKey();

                        String name = mRollSnap.child("basic").child("fb01name").getValue().toString();
                        String number = (String) mRollSnap.child("basic").child("fb04roll").getValue().toString();
                        if(name == null){
                            Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
                        }
                        basic model = new basic(name,number);
                        tvName.setText(name);
                        tvRoll.setText(number);

                    }
                }
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) { }
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM