从 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 1
和T1
的路径与T2
不同。正如我在您的数据库架构中看到的,您的 T2
作为一个额外的孩子 (-LH-3 ... GbsF
),它是由 push()
方法生成的。为了正确显示所有这些对象,您需要为所有对象设置相同的路径。因此,您可以通过使用push()
方法以相同方式添加Studio 1
和T1
或不使用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 1
和T1
,然后尝试再次添加T2
,不使用push() 方法,现在三个对象都正确显示了吗?
不使用 .push() 方法的问题会覆盖整个数据库。所以我需要使用随机生成的密钥从不同的引用中读取数据。
在这种情况下,使用push()
方法,但不再使用该地图,只需使用mDataBaseRef.push().setValue(firebaseMarker);
,就像我更新的答案一样。
使用您的答案,它将数据存储在 push 方法中随机生成的密钥下,没有额外的孩子,但它仍然不会将标记添加到地图中。以上是关于从 Google Firebase 实时数据库读取 google maps 标记数据时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
Android-从Firebase实时数据库读取数据并显示在RecyclerView上
从Firebase实时数据库读取Android数据并在RecyclerView上显示