当前位置: 首页 > 知识库问答 >
问题:

多个(嵌套的)ValueEventListeners不能在android的firebase实时数据库中工作

陶涵育
2023-03-14

我正在做的项目在firebase实时数据库中有3个“表”,即:

用户(包括用户的登录信息,如电子邮件、密码、手机号码等)

viscripprofiles(包含基本的配置文件信息,如配置文件pic字符串、姓名、职务和来自Users表的相应用户ID)

志愿者配置文件(包含地址、纬度、经度、可用性时间以及相应的用户ID和受害者配置文件ID(由Firebase生成))

    public void DropVolunteerMarkers()
    {
        //DROP ALL MARKERS FUNCTION
        volunteerDatabaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot volunteerprofile:dataSnapshot.getChildren())
                {

                    key=(String) volunteerprofile.child("UserID").getValue();
                    victimID=(String) volunteerprofile.child("VictimProfileID").getValue();
                    getVictimInfo();//GET NAME,PIC,JOB TITLE FROM THE VICTIM TABLE FOR THIS SPECIFIC VOLUNTEER
                    getUserInfo();//GET EMAIL AND PHONE NUMBER FROM USERS TABLE FOR THIS SPECIFIC VOLUNTEER
                    String currentuserid=SaveSharedPreference.getUserName(FindNearbyVolunteers.this);
                    if(!key.equals(currentuserid))//TO AVOID CURRENT USER BEING SHOWN AS A VOLUNTEER
                    {
                        address= (String)volunteerprofile.child("Address").getValue();
                        availabiliity=(String)volunteerprofile.child("Availability").getValue();
                        String LAT= (String) volunteerprofile.child("Latitude").getValue();
                        String LNG= (String) volunteerprofile.child("Longitude").getValue();
                        Toast.makeText(FindNearbyVolunteers.this,LAT+", "+LNG,Toast.LENGTH_SHORT).show();
                        Double Lat= Double.parseDouble(LAT);
                        Double Long= Double.parseDouble(LNG);
                        LatLng latLng = new LatLng(Lat,Long);
                        MarkerOptions markerOptions = new MarkerOptions();
                        markerOptions.position(latLng);
                        Toast.makeText(FindNearbyVolunteers.this,key+", "+victimID+", "+name+", "+jobtitle+", "+availabiliity+", "+email+", "+address,Toast.LENGTH_LONG).show();
                        //mMap.setInfoWindowAdapter(new VolunteerPopupAdapter(FindNearbyVolunteers.this,name,jobtitle,availabiliity,email,address,dp,number));
                        markerOptions.title(volunteerprofile.getKey().toString());
                        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
                        mCurrLocationMarker = mMap.addMarker(markerOptions);
                    }
                    else{
                        //IN CASE OF CURRENT USER
                            //Place current location marker
                            LatLng latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
                            MarkerOptions markerOptions = new MarkerOptions();
                            markerOptions.position(latLng);
                            markerOptions.title("YOU");
                            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
                            mCurrLocationMarker = mMap.addMarker(markerOptions);
                }}

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
 private void getVictimInfo()
    {
        victimDatabaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot victimProfile:dataSnapshot.getChildren())
                {
                    if(victimProfile.getKey().equals(victimID))
                    {
                        dp=(String)victimProfile.child("DP").getValue();
                        jobtitle=(String)victimProfile.child("JobTitle").getValue();
                        name=(String)victimProfile.child("Name").getValue();

                    }
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

    }
        private void getUserInfo(){
        userDatabaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot userProfile:dataSnapshot.getChildren())
                {
                    if(userProfile.getKey().equals(key))
                    {
                        email=(String)userProfile.child("Email").getValue();
                        number=(String)userProfile.child("Mobile").getValue();;

                    }
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
 DatabaseReference volunteerDatabaseReference,userDatabaseReference,victimDatabaseReference;
String dp,jobtitle="no value",name="no value";
String email="no value",number="no value",address="no value",availabiliity="no value",victimID,key;

我的数据库截图在这里输入图像描述

共有1个答案

燕和裕
2023-03-14

您现在不能使用尚未加载的东西。换句话说,您不能简单地将dpjobtitleemail声明为全局变量并在ondatachange()方法之外使用它们,因为由于该方法的异步行为,它将始终为null。这意味着,当您试图在该方法之外使用这些值时,数据还没有完成从数据库加载,这就是为什么无法访问,并且总是获得null,这就是为什么数据库中没有写入任何内容。

这个问题的一个快速解决方案是只在ondatachange()方法中使用所有这些值,或者如果您想在外部使用它们,我建议您深入到异步世界,并查看本文中anwser的最后一部分,其中我解释了如何使用自定义回调来实现它。你也可以看看这个视频,以便更好地理解。

 类似资料:
  • 我正在尝试运行Firebase实时数据库查询,以根据从根嵌套在第4级的值过滤数据。下面是数据结构,我的查询是: 但是这个查询没有返回任何数据。我已经启用了索引,但没有任何警告。我还将我的查询改为< code >。order by child(' info status '),但没有结果。 如果我将ref设置为低于一个级别,即,那么它会成功获得结果。但是在我的场景中,我没有可以在中使用的用户ID。

  • 我在firebase中具有以下结构。 为了检索数据,我使用以下代码- 调用onDataChange()时,p0包含除组数据之外的所有其他数据。 这是我的dataclass用户模型- 这是我收到的数据快照- datasnapshot!中没有组!。 更新添加了此行mFirebaseDatabaseReference?。保持同步(错误)。它昨天工作了几次,现在不工作了!

  • 当我试图删除或编辑实时数据库中的节点时,我总是得到这样的信息:我必须选择一个元素较少的键来更改某些内容,否则它是只读的。 但是当我单击低级节点时,没有任何反应。因此,我实际上可以从控制台:( 一周前,我没有看到这个警告,一切都很好!知道如何回到工作版本吗? 我也觉得德语翻译的不太好,因为它告诉我应该激活另一种模式。用英语说,模式被激活。

  • 我正在尝试检索一些值而不是其他值。事实上,我想通过用户的名字来搜索他们。 我尝试使用和,但找不到正确的解决方案。 如您所见,我还添加了。如果我不添加那个部分,它就不会检索任何东西。我想要的只是从我在TextField中所写的内容开始检索值。

  • 我在从Firebase实时数据库查询嵌套数据时遇到问题。 给出以下示例数据结构: 让我们假设这个集合将有数百个孩子。此外,在执行查询之前,ID是随机的和未知的。如图所示,每个交叉点都有几个其他值。 首先,我必须列出键以给定值开始的所有交叉。例如,如果我搜索1,我希望得到这个简单例子中的所有交叉。 此代码段解决了这个问题。虽然,我仍然不确定这是否是实现这一目标的最佳方式。 我的主要问题是,现在我必须

  • 我在Firebase项目中使用多个数据库。主(默认)数据库的云函数工作得很好,但是,我不能让它们用于辅助数据库。例如,我想在具有管理员权限的节点上发出读取请求: 这在主数据库中有效,但是,如果我想在另一个数据库上执行该命令,则不起作用: 虽然已经部署了这些功能,但是当我试图执行云功能时,控制台上出现了一个错误。 以下是带有https触发器的云函数的代码: 下面是Firebase控制台中的错误日志: