简体   繁体   English

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

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

I am making an android app using the firebase Realtime database.我正在使用 firebase 实时数据库制作 android 应用程序。 My rules structure is given below:我的规则结构如下:

{
// 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"
      }
    }
  }
}

It means that a user should be signed in as an authenticated user to write some data.这意味着用户应该以经过身份验证的用户身份登录才能写入一些数据。 But when it comes to read no sign in is required.但是在阅读时不需要登录。

Now I need to ignore the uid of the user to give free access to other users( ie without signing in).现在我需要忽略用户的uid以免费访问其他用户(即无需登录)。 在此处输入图像描述

This is the java code I am using currently to read data.这是我目前用来读取数据的 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) {

            }

        });

I could not decide what to write instead of the first child to read any data without signing in.我无法决定写什么而不是第一个孩子在没有登录的情况下读取任何数据。

.child("GcZoeK7JIbNWVOog6ZjUPiBfxwn2")

Please guide me How to ignore this child?请指导我如何忽略这个孩子? Any help will be appreciated.任何帮助将不胜感激。

EDIT The advice "try to refrain from using deeply nested children" by @Abdullah Z Khan further provided me insight into the problem.编辑@Abdullah Z Khan 的“尽量避免使用深度嵌套的孩子”的建议进一步让我深入了解了这个问题。 I changed my codes as given below:我更改了我的代码,如下所示:

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

            }

        });

Although this PLAN B has temporarily relieved me a bit yet the question is still unanswered.Beacuse I have to write the uid code of users each time they join the app( and have to update and publish the app again and again.A better solution is awaited.虽然这个PLAN B暂时让我松了口气,但问题仍然没有得到解答。因为每次加入应用程序时我都必须编写用户的uid代码(并且必须一次又一次地更新和发布应用程序。更好的解决方案是等待着。

EDIT: Added values in >>> marked lines for understanding编辑:>>>标记行中添加值以供理解

From what is given, this is your database structure:从给出的内容来看,这是您的数据库结构:

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

            }
        }
    }
}

Because it is so much nested (I'd suggest a different hierarchy altogether), there is no easy way to access a child with an unknown parent as is.因为它是如此嵌套(我建议完全不同的层次结构),所以没有简单的方法可以按原样访问具有未知父级的子级。 However, if you can change the database structure to this:但是,如果您可以将数据库结构更改为:

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

            }
        }
    }
}

You'll get a uid lookup table.您将获得一个 uid 查找表。 You can then use that to reach the node.然后,您可以使用它来到达节点。 Keep in mind this isn't a direct answer to what you asked, which is how to get a nested node(not value) without knowing the parent, but here you can dynamically access uids of whatever school is needed, assuming each school has exactly one parent.请记住,这不是您所问问题的直接答案,即如何在不知道父级的情况下获取嵌套节点(不是值),但在这里您可以动态访问所需学校的 uid,假设每所学校都有一位家长。

After that, nest your listener:之后,嵌套你的监听器:

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

            }

        });

In practice, try to refrain from using deeply nested children, rather use references to other nodes.在实践中,尽量避免使用深度嵌套的子节点,而是使用对其他节点的引用。

I hope this helps!!我希望这有帮助!!

how about this:这个怎么样:

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

        }

    });

Well, I don't know if I understood your question, but if you are trying to read the children of all the nodes without specifying them, you can try to do something like the code below: (I didn't test it, I just changed your sample)好吧,我不知道我是否理解你的问题,但是如果你试图读取所有节点的子节点而不指定它们,你可以尝试执行下面的代码:(我没有测试它,我刚刚改变了你的样本)

    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.

相关问题 如何在 Android Studio 中使用来自 Firebase 数据库的查询在不使用唯一 ID 的情况下获取子节点? - How to Fetch child nodes without using unique ids using Query from Firebase database in Android Studio? 如何在Firebase数据库Android上获取具有相似子节点的所有父节点? - How to fetch all parent nodes with similar child nodes on Firebase database Android? 如何使用Java从XML读取父节点的子节点 - How to read child nodes of a parent node from XML using java 访问 Android 的 Firebase 中的父节点和子节点 - Accessing parent and child nodes in Firebase for Android 如何在 android 工作室中从 firebase 检索多个子节点 - How to retrieve mulitple child nodes from firebase in android studio Android-Firebase数据库子节点 - Android - Firebase database child node Android,Firebase-尝试检索多个子节点时,数据库仅将单个子节点作为字符串返回 - Android, Firebase - database only returns single child node as string when trying to retrieve multiple child nodes Firebase数据库从子android访问节点 - Firebase Database accessing nodes from child android android studio firebase 数据库:如何从子子节点获取数据 - android studio firebase database: how to get data from sub child 如何在 Firebase 数据库 Android Studio 中保持领先地位 - How to stay on top child in Firebase Database Android Studio
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM