将 Firebase 中的数据显示到自定义信息窗口中

Posted

技术标签:

【中文标题】将 Firebase 中的数据显示到自定义信息窗口中【英文标题】:Displaying data from Firebase into custom Info Window 【发布时间】:2021-12-14 08:42:50 【问题描述】:

在从数据库中检索位置数据后,我正在尝试将几个用户详细信息从 Firebase 显示到自定义地图标记中,但我不知道我应该实施 FirebaseRecyclerAdapter 还是普通的。我该怎么做?

我正在尝试至少检索用户的姓名、紧急情况类型和警报级别,并在单击标记时显示在信息窗口中:


  "Blocked Users" : 
    "RCX2HZXIwlSmMHFgDytf1DgZBgi2" : 0,
    "vqP3H4maEfQxCBHEWqsH9q4O1M52" : 0
  ,
  "User Location" : 
    "RCX2HZXIwlSmMHFgDytf1DgZBgi2" : 
      "latitude" : 15.506605,
      "longitude" : 120.86838
    ,
    "vqP3H4maEfQxCBHEWqsH9q4O1M52" : 
      "latitude" : 37.3259633,
      "longitude" : -121.898475
    
  ,
  "Users" : 
    "RCX2HZXIwlSmMHFgDytf1DgZBgi2" : 
      "Alert Level" : "High",
      "Emergency Type" : "Natural Disaster",
      "address" : "Lapaz Tarlac",
      "emergencyNum" : "0981232387346",
      "name" : "Rafael Campos",
      "phoneNum" : "0981233445675"
    ,
    "vqP3H4maEfQxCBHEWqsH9q4O1M52" : 
      "Alert Level" : "High",
      "Emergency Type" : "Natural Disaster",
      "address" : "Lapaz Tarlac",
      "emergencyNum" : "9876876650987",
      "name" : "Rafael Campos",
      "phoneNum" : "089098786876"
    
  

这是我的 onMapReady():

@Override
    public void onMapReady(@NonNull GoogleMap googleMap) 
        mMap = googleMap;

        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference locationRef = rootRef.child("User Location");



        locationRef.addChildEventListener(new ChildEventListener() 
            @Override
            public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) 


                    LocationSend send = snapshot.getValue(LocationSend.class);
                    LatLng location = new LatLng(send.getLatitude(), send.getLongitude());
                    mMap.addMarker(new MarkerOptions().position(location).title(getCompleteAddress(send.getLatitude(), send.getLongitude())));
                    mMap.moveCamera(CameraUpdateFactory.newLatLng(location));
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 14F));
                    mMap.setInfoWindowAdapter(new InfoWindowAdapter(Retrieve.this));
                    Log.d("TAG", "latitude, longitude");
                    notification();
            

            @Override
            public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) 
                LocationSend send = snapshot.getValue(LocationSend.class);
                notification();
            

            @Override
            public void onChildRemoved(@NonNull DataSnapshot snapshot) 

            

            @Override
            public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) 

            

            @Override
            public void onCancelled(@NonNull DatabaseError error) 

            
        );
    

我的适配器:

public class InfoWindowAdapter implements GoogleMap.InfoWindowAdapter

    Context context;
    public InfoWindowAdapter(Context context)
        this.context = context;
    

    @Nullable
    @Override
    public View getInfoWindow(@NonNull Marker marker) 
        View infoView = LayoutInflater.from(context).inflate(R.layout.infowindow, null);
        TextView title = infoView.findViewById(R.id.title);
        TextView alert = infoView.findViewById(R.id.alert);
        TextView type = infoView.findViewById(R.id.type);
        title.setText(marker.getTitle());
        alert.setText(marker.getSnippet());
        type.setText(marker.getSnippet());

        return infoView;
    

    @Nullable
    @Override
    public View getInfoContents(@NonNull Marker marker) 
        return null;
    

【问题讨论】:

您能否指出您想要获取的确切数据? 在用户节点中,名称、紧急类型和警报级别 【参考方案1】:

根据你上一条评论:

在用户节点中,名称、紧急类型和警报级别

为了能够获取与特定用户对应的指定字段的值并将其添加到 Google 地图,请使用以下代码行:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userLocationRef = rootRef.child("User Location").child(uid);
userLocationRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() 
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> userLocationTask) 
        if (userLocationTask.isSuccessful()) 
            DataSnapshot userLocationSnapshot = userLocationTask.getResult();
            double latitude = userLocationSnapshot.child("latitude").getValue(Double.class);
            double longitude = userLocationSnapshot.child("longitude").getValue(Double.class);

            DatabaseReference uidRef = rootRef.child("Users").child(uid);
            uidRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() 
                @Override
                public void onComplete(@NonNull Task<DataSnapshot> userTask) 
                    if (userTask.isSuccessful()) 
                        DataSnapshot userSnapshot = userTask.getResult();
                        String name = userSnapshot.child("Name").getValue(String.class);
                        String emergencyType = userSnapshot.child("Emergency Type").getValue(String.class);
                        String alertLevel = userSnapshot.child("Alert Level").getValue(String.class);

                        MarkerOptions markerOptions = new MarkerOptions();
                        LatLng latLng = new LatLng(latitude, longitude);
                        markerOptions.position(latLng);
                        markerOptions.title(name + "/" + emergencyType + "/" + alertLevel);
                        googleMap.addMarker(markerOptions);
                     else 
                        Log.d("TAG", userTask.getException().getMessage()); //Don't ignore potential errors!
                    
                
            );
         else 
            Log.d("TAG", userLocationTask.getException().getMessage()); //Don't ignore potential errors!
        
    
);

以下代码的结果将是添加一个标记,该标记对应于 Google 地图上的用户位置。标记的标题将包含名称、紧急情况类型和警报级别。

这确实适用于单个用户,如果您需要显示所有用户,则只需使用 getChildren() 方法遍历 DataSnapshot 对象,如下所示:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userLocationRef = rootRef.child(uid).child("User Location");
userLocationRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() 
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> userLocationTask) 
        if (userLocationTask.isSuccessful()) 
            for (DataSnapshot userLocationSnapshot : userLocationTask.getResult().getChildren()) 
                double latitude = userLocationSnapshot.child("latitude").getValue(Double.class);
                double longitude = userLocationSnapshot.child("longitude").getValue(Double.class);

                DatabaseReference usersRef = rootRef.child("Users").child(uid);
                usersRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() 
                    @Override
                    public void onComplete(@NonNull Task<DataSnapshot> userTask) 
                        if (userTask.isSuccessful()) 
                            for (DataSnapshot userSnapshot : userTask.getResult().getChildren()) 
                                String name = userSnapshot.child("name").getValue(String.class);
                                String emergencyType = userSnapshot.child("Emergency Type").getValue(String.class);
                                String alertLevel = userSnapshot.child("Alert Level").getValue(String.class);

                                MarkerOptions markerOptions = new MarkerOptions();
                                LatLng latLng = new LatLng(latitude, longitude);
                                markerOptions.position(latLng);
                                markerOptions.title(name + "/" + emergencyType + "/" + alertLevel);
                                googleMap.addMarker(markerOptions);
                            
                         else 
                            Log.d("TAG", userTask.getException().getMessage()); //Don't ignore potential errors!
                        
                    
                );
            
         else 
            Log.d("TAG", userLocationTask.getException().getMessage()); //Don't ignore potential errors!
        
    
);

【讨论】:

以上是关于将 Firebase 中的数据显示到自定义信息窗口中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中以编程方式触发自定义信息窗口

Firebase onCreate 向 auth.user 添加自定义声明

删除谷歌地图中的自定义信息窗口后如何取消选择 GMSMarker

Firebase 自定义声明允许的数据类型是啥?

无法获得Android系统中googlemap V2上标记的自定义信息窗口的点击事件。

Firebase 自定义声明不会传播