从 Firebase 为每个特定帖子检索特定数据的比 datasnapshot 更好的方法?返回的位置错误
Posted
技术标签:
【中文标题】从 Firebase 为每个特定帖子检索特定数据的比 datasnapshot 更好的方法?返回的位置错误【英文标题】:Better way than datasnapshot to retrieve specific data from Firebase for each specific post? Location returned is wrong 【发布时间】:2020-05-12 03:02:22 【问题描述】:需要从 Firebase 检索每个特定事件的 Latitude
和 Longitude
,其中用户在创建事件时还通过在特定位置设置标记来选择事件位置(Latitude
和 Longitude
)。
我遇到的问题是保存的最后一个事件会覆盖所有其他现有事件位置,因此当您点击TextView
将您带到GoogleMaps
以向您显示事件将在哪里发生时,只有最后一个事件的保存的位置出现。但显然每个事件都有其特定的位置。
例如,如果我创建了三个事件并且它们的位置是罗马、柏林和莫斯科,那么将在 GoogleMap
上创建的唯一标记将是莫斯科的事件,因为那是最后保存的位置。
我希望当第二个用户使用每个特定于事件的postid
来点击TextView
时,可以在数据库中找到该事件并将其特定坐标显示在地图上。有人可以帮我实现这一目标吗?我一直在尝试使用datasnapshot
来实现这一目标,但我一直无法找到其他活动地点。我总是只为所有帖子保存最后一个事件的位置。有没有比datasnapshot
更好的方法?
希望下面的图片有助于弄清楚我的数据结构是如何组织的。
Firebase data structure
MapsActivityUser.java
public class MapsActivityUser extends FragmentActivity implements OnMapReadyCallback
private GoogleMap map;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_user);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
@Override
public void onMapReady(GoogleMap googleMap)
map = googleMap;
final DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
for (DataSnapshot snapshot : dataSnapshot.getChildren())
Post post = snapshot.getValue(Post.class);
if (post != null)
double latitude = post.getLocation().getLatitude();
double longitude = post.getLocation().getLongitude();
LatLng location = new LatLng(latitude, longitude);
map.addMarker(new MarkerOptions().position(location).title("Event location"));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 10));
else
Toast.makeText(MapsActivityUser.this, "Event doesn't have location on Map", Toast.LENGTH_SHORT).show();
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
);
【问题讨论】:
如果评论此行map.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 10));
并增加缩放比例,您会看到所有标记吗?
@AlexMamo 是的,你是对的,我看到了所有的标记。我怎样才能让它只出现特定事件位置的标记而其他不出现?
请在下面查看我的答案。
【参考方案1】:
您的代码中的问题是使用了以下代码行:
map.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 10));
在for循环内部,这基本上意味着您的相机将被移动到循环中迭代的最后一个位置。但是,如果您增加缩放比例,您将能够看到地图上的所有位置。根据您最后的评论:
我怎样才能使它只出现特定事件位置的标记而其他不出现?
在这种情况下,您应该使用查询。基本上你会告诉 Firebase 只返回一个与你的查询匹配的位置。这应该是这样的:
Query query = reference.orderByChild("locationName").equalTo("locationName");
现在,只需在此 query
上附加一个侦听器并在地图上添加标记。在这种情况下,建议将相机移动到该位置,因为您只能获得一个位置。但请注意,如果您有唯一的位置名称,则此查询将起作用。如果您还存储位置的 id,那么您只能使用如下所示的 DatabaseReference
:
DatabaseReference locationRef = reference.child(locationId);
附加一个监听器并在地图上添加标记。
编辑:
要获取经纬度,请使用以下代码行:
Query query = reference.orderByChild("postid").equalTo("-LzNDAXtnT6NXYK2XYPK");
ValueEventListener valueEventListener = new ValueEventListener()
@Override
public void onDataChange(DataSnapshot dataSnapshot)
for(DataSnapshot ds : dataSnapshot.getChildren())
double latitude = ds.child("location").child("latitude").getValue(Double.class);
double longitude = ds.child("location").child("longitude").getValue(Double.class);
Log.d(TAG, latitude + ", " + longitude);
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
;
query.addListenerForSingleValueEvent(valueEventListener);
【讨论】:
好的,有一个问题——如果该位置是一个有两个子节点(Latitude
和Longitude
)的节点,它存储位置数据,那么我只做DatabaseReference locationRef = reference.child(location);
。因为位置不保存为城市名称,所以它们保存为Longitude
和Latitude
坐标
在上图中可以看到位置数据是如何存储在 Firebase 中的
你不认为我这样做会更好DatabaseReference reference = FirebaseDatabase.getInstance.getReference("Posts").child(postid);
???
我已经用获得latitude
和longitude
的代码更新了我的答案。请检查一下。
Alex,这不是只返回特定 postid "-LzNDAXtnT6NXYK2XYPK"
的位置吗?我需要当用户点击帖子时,该帖子的特定位置的任何帖子都回来......并且每个帖子都有自己独特的postid......【参考方案2】:
监听集合回调(查询快照), 在回调运行forloop中,您将获得documentchanges类,您将在其中添加,删除,修改指示器,这表明何时添加,删除和修改数据,相应地执行您的逻辑。 要获取文档,请使用 getId,它将返回集合中存在的所有文档 ID。 我不在电脑前,请在 Google 上查看。
我会尽快编辑解决方案。
【讨论】:
您可以编辑您的答案以反映您正在谈论的代码吗?我仍然不知道该怎么做。谢谢以上是关于从 Firebase 为每个特定帖子检索特定数据的比 datasnapshot 更好的方法?返回的位置错误的主要内容,如果未能解决你的问题,请参考以下文章
Firebase GeoFire,从我当前位置检索具有特定半径的帖子
如何使用 Firebase 实时数据库创建特定用户所有已保存帖子的列表?