从 Google Firebase 实时数据库读取 google maps 标记数据时出现问题

Posted

技术标签:

【中文标题】从 Google Firebase 实时数据库读取 google maps 标记数据时出现问题【英文标题】:Having problems reading google maps marker data from Google Firebase Realtime Database 【发布时间】:2018-12-19 13:46:35 【问题描述】:

我有一个 Firebase 实时数据库,用于存储 Google 地图标记数据。它看起来像这样:Firebase Database

我的应用程序可以选择将您自己的标记添加到数据库中,我的问题是我的应用程序仅从 Studio 1 和 T1 读取信息,而不是从 .push() 添加的随机密钥中读取信息。当我通过应用程序添加标记时。关于如何让它读取随机密钥下的标记信息的任何想法?我的代码如下所示:

public class MapsActivity extends FragmentActivity implements 
OnMapReadyCallback, GoogleMap.OnMarkerClickListener 

FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference mProfileRef = firebaseDatabase.getReference("Studios");
ChildEventListener mChildEventListener;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    Button addAStudio = (Button) findViewById(R.id.addAStudio);
    addAStudio.setOnClickListener(new Button.OnClickListener() 
        public void onClick(View v) 
            Intent intent = new Intent(MapsActivity.this, Rent.class);
            startActivity(intent);
        
    );


@Override
public void onMapReady(GoogleMap googleMap)
    googleMap.setOnMarkerClickListener(this);
    LatLng  Copenhagen = new LatLng(55.67, 12.56);
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Copenhagen, 18));
    googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    //get marker info from Firebase Database and add to map
    addMarkersToMap(googleMap);

    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        return;
    
    googleMap.setMyLocationEnabled(true);


@Override
public void onStop()
    if(mChildEventListener != null)
        mProfileRef.removeEventListener(mChildEventListener);
    super.onStop();


private void addMarkersToMap(final GoogleMap map)

    mChildEventListener = mProfileRef.addChildEventListener(new ChildEventListener() 



        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) 

                FirebaseMarker marker = dataSnapshot.getValue(FirebaseMarker.class);
                String StudioName = marker.getStudioName();
                String StudioAdress = marker.getStudioAddress();
                String StudioDescription = marker.getStudioDescription();
                double latitude = marker.getLatitude();
                double longitude = marker.getLongitude();
                LatLng location = new LatLng(latitude, longitude);

                map.addMarker(new MarkerOptions()
                        .position(location)
                        .title(StudioName)
                        .snippet(StudioAdress)
                        .snippet(StudioDescription))
                        .showInfoWindow();

        

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) 

        

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) 

        

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) 

        

        @Override
        public void onCancelled(DatabaseError databaseError) 

        

    );


@Override
public boolean onMarkerClick(Marker marker) 
    return false;

public class FirebaseMarker 

public String studioName;
public String studioDescription;
public String studioAddress;
public double latitude;
public double longitude;


//required empty constructor
public FirebaseMarker() 


public FirebaseMarker(String studioName, String studioDescription, String studioAdress, double latitude, double longitude) 
    this.studioName = studioName;
    this.studioDescription = studioDescription;
    this.studioAddress = studioAdress;
    this.latitude = latitude;
    this.longitude = longitude;


public String getStudioName() 
    return studioName;


public void setStudioName(String studioName) 
    this.studioName = studioName;


public String getStudioDescription() 
    return studioDescription;


public void setStudioDescription(String studioDescription) 
    this.studioDescription = studioDescription;


public String getStudioAddress() 
    return studioAddress;


public void setStudioAddress(String studioAddress) 
    this.studioAddress = studioAddress;


public double getLongitude() 
    return longitude;


public void setLongitude(double longitude) 
    this.longitude = longitude;


public double getLatitude() 
    return latitude;


public void setLatitude(double latitude) 
    this.latitude = latitude;

最后在哪里向数据库添加一个新的标记:

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rent);
    saveStudio = findViewById(R.id.saveStudio);
    studioNameTextField = findViewById(R.id.studioNameTextField);
    studioInfoTextField = findViewById(R.id.studioInfoTextField);
    studioAdressTextField = findViewById(R.id.studioAdressTextField);
    mDatabase = FirebaseDatabase.getInstance();
    mDataBaseRef = mDatabase.getReference("Studios");
    saveStudio = findViewById(R.id.saveStudio);


    saveStudio.setOnClickListener(new Button.OnClickListener() 
        public void onClick(View v) 

                Map<String, FirebaseMarker> newStudioAdd = new HashMap<>();

                newStudioAdd.put(studioNameTextField.getText().toString(),
                        new FirebaseMarker(
                                studioNameTextField.getText().toString(),
                                studioInfoTextField.getText().toString(),
                                studioAdressTextField.getText().toString(),
                                53.669115, 12.560311
                        )
                );

                mDataBaseRef.push().setValue(newStudioAdd);

          Intent intent = new Intent(Rent.this, MapsActivity.class);
          startActivity(intent);

        
    );


到目前为止,纬度和经度是硬编码的,因为我希望它在继续之前读取标记。

【问题讨论】:

【参考方案1】:

这是因为Studio 1T1 的路径与T2 不同。正如我在您的数据库架构中看到的,您的 T2 作为一个额外的孩子 (-LH-3 ... GbsF),它是由 push() 方法生成的。为了正确显示所有这些对象,您需要为所有对象设置相同的路径。因此,您可以通过使用push() 方法以相同方式添加Studio 1T1 或不使用push() 方法添加T2 来实现此目的。

FirebaseMarker firebaseMarker = new FirebaseMarker(
    studioNameTextField.getText().toString(),
    studioInfoTextField.getText().toString(),
    studioAdressTextField.getText().toString(),
    53.669115, 12.560311);
mDataBaseRef.push().setValue(firebaseMarker);

假设 Studios 节点是您的 Firebase 数据库的直接子节点,您可以通过以下方式在地图上添加标记:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference studiosRef = rootRef.child("Studios");
ValueEventListener valueEventListener = new ValueEventListener() 
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) 
        for(DataSnapshot ds : dataSnapshot.getChildren()) 
            FirebaseMarker marker = dataSnapshot.getValue(FirebaseMarker.class);
            String StudioName = marker.getStudioName();
            String StudioAdress = marker.getStudioAddress();
            String StudioDescription = marker.getStudioDescription();
            double latitude = marker.getLatitude();
            double longitude = marker.getLongitude();
            LatLng location = new LatLng(latitude, longitude);

            map.addMarker(new MarkerOptions()
                    .position(location)
                    .title(StudioName)
                    .snippet(StudioAdress)
                    .snippet(StudioDescription))
                    .showInfoWindow();
        
    

    @Override
    public void onCancelled(DatabaseError databaseError) 
;
studiosRef.addListenerForSingleValueEvent(valueEventListener);

【讨论】:

我刚刚移除了 Studio 1 和 T1,并使用 push 方法添加了两个新的 studio。现在三个人都没有出现。我认为随机生成的密钥(额外的孩子)以某种方式把事情搞砸了。 是的,这是预期的行为。您现在正试图从错误的引用中读取数据。尝试其他解决方案。像以前一样添加Studio 1T1,然后尝试再次添加T2,不使用push() 方法,现在三个对象都正确显示了吗? 不使用 .push() 方法的问题会覆盖整个数据库。所以我需要使用随机生成的密钥从不同的引用中读取数据。 在这种情况下,使用push() 方法,但不再使用该地图,只需使用mDataBaseRef.push().setValue(firebaseMarker);,就像我更新的答案一样。 使用您的答案,它将数据存储在 push 方法中随机生成的密钥下,没有额外的孩子,但它仍然不会将标记添加到地图中。

以上是关于从 Google Firebase 实时数据库读取 google maps 标记数据时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

使用颤振从 Firebase 实时数据库中读取子节点的数量

Android-从Firebase实时数据库读取数据并显示在RecyclerView上

从Firebase实时数据库读取Android数据并在RecyclerView上显示

如何限制从 Firebase 读取数据的速率?

Google Firebase实时数据库updateChildren()方法不起作用? [关闭]

Firebase 实时数据库中有关身份验证的信息