繁体   English   中英

从 Firebase 为每个特定帖子检索特定数据比 datasnapshot 更好的方法? 返回的位置错误

[英]Better way than datasnapshot to retrieve specific data from Firebase for each specific post? Location returned is wrong

需要从 Firebase 检索每个特定事件的LatitudeLongitude ,其中用户在创建事件时还通过在特定位置设置标记来选择事件位置( LatitudeLongitude )。

我遇到的问题是,保存的最后一个事件覆盖了所有其他现有的事件位置,因此当您点击TextView将您带到GoogleMaps以显示事件将发生的位置时,只会出现保存的最后一个事件的位置。 但显然每个事件都有其特定的位置。

例如,如果我创建了三个事件并且它们的位置是罗马、柏林和莫斯科,那么将在GoogleMap上创建的唯一标记将是莫斯科的事件,因为这是最后保存的位置。

我希望当第二个用户使用每个特定于事件的postid来点击TextView postid ,该事件将在数据库中找到,并将其特定坐标显示在地图上。 有人可以帮助我实现这一目标吗? 我一直在尝试使用datasnapshot来实现这datasnapshot ,但我一直无法找到其他事件位置。 我总是只为所有帖子保存最后一个事件的位置。 有没有比datasnapshot更好的方法呢?

下图希望有助于弄清楚我的数据结构是如何组织的。

Firebase 数据结构

地图活动用户.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));

在 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);

侦听集合回调(查询快照),在回调运行 forloop 中,您将获得 documentchanges 类,您将在其中添加、删除、修改指示符,这指示何时添加、删除和修改数据,相应地执行您的逻辑。 获取文档使用 getId 它将返回集合中存在的所有文档 ID。 我不在电脑前,只需在谷歌上查看。

我会尽快编辑解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM