如何在androidstudio中读取firebase数据库中的子节点而不提及父节点?

knsnq2tg  于 2021-07-03  发布在  Java
关注(0)|答案(3)|浏览(411)

我正在使用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")

请指导我如何忽略这个孩子?任何帮助都将不胜感激。
编辑@abdullahz 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) {

            }

        });

虽然这个b计划暂时让我松了一口气,但这个问题仍然没有答案。因为每次用户加入应用程序时,我都要编写用户的uid代码(并且要一次又一次地更新和发布应用程序。等待更好的解决方案。

2mbi3lxu

2mbi3lxu1#

编辑:在>>>标记行中添加值以便于理解
根据给出的内容,这是您的数据库结构:

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

            }

        });

在实践中,尽量避免使用深度嵌套的子节点,而是使用对其他节点的引用。
我希望这有帮助!!

ds97pgxw

ds97pgxw2#

这个怎么样:

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

        }

    });
9lowa7mx

9lowa7mx3#

好吧,我不知道我是否理解你的问题,但是如果你试图读取所有节点的子节点而不指定它们,你可以尝试执行下面的代码:(我没有测试它,我只是更改了你的示例)

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

相关问题