【问题标题】:Problem to retrive realtime data from Firebase DB into google maps将实时数据从 Firebase DB 检索到谷歌地图的问题
【发布时间】:2019-06-14 05:46:03
【问题描述】:

我正在尝试从 Firebase 数据库中检索实时位置数据,并在 Google 地图中为每个用户显示多个标记。

这是我的 Firebase 数据库的结构:

这是谷歌地图活动的代码:

public class CyclistMapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private FirebaseAuth mAuth;
    private DatabaseReference UserRef;
    private String currentUserID;
    private static final String TAG = CyclistMapsActivity.class.getSimpleName();
    private HashMap<String, Marker> mMarkers = new HashMap<>();

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cyclist_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);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMaxZoomPreference(16);
        subscribeToUpdates();
    }

    private void subscribeToUpdates() {
        mAuth = FirebaseAuth.getInstance();
        currentUserID = mAuth.getCurrentUser().getUid();
        final String path = "/latlong";
        UserRef = FirebaseDatabase.getInstance().getReference("Users"+currentUserID+path);

        DatabaseReference ref = UserRef;
        ref.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                setMarker(dataSnapshot);
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
                setMarker(dataSnapshot);
            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
            }

            @Override
            public void onCancelled(DatabaseError error) {
                Log.d(TAG, "Failed to read value.", error.toException());
            }
        });
    }

    private void setMarker(DataSnapshot dataSnapshot) {
        String key = dataSnapshot.getKey();
        HashMap<String, Object> value = (HashMap<String, Object>) dataSnapshot.child("Users").child(currentUserID).child("/latlong").getValue();
        double lat = Double.parseDouble(value.get("latitude").toString());
        double lng = Double.parseDouble(value.get("longitude").toString());
        LatLng location = new LatLng(lat, lng);

        if (!mMarkers.containsKey(key)) {
            mMarkers.put(key, mMap.addMarker(new MarkerOptions().title(key).position(location)));
        } else {
            mMarkers.get(key).setPosition(location);
        }
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (Marker marker : mMarkers.values()) {
            builder.include(marker.getPosition());
        }
        mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 300));
    }
}

当我尝试运行我的应用时,所有用户的位置在 Firebase 数据库中每 5 秒更新一次,但制造商并未显示在 Google 地图上。

我在我的 logcat 中看到了这个错误:

"W/Bundle: Key getPairValue() expected String but value was a java.lang.Float.  The default value <null> was returned."

【问题讨论】:

    标签: android firebase google-maps firebase-realtime-database


    【解决方案1】:

    您的代码中有几个问题。你的引用在"Users"+currentUser之间不包含/,应该是"Users/"+currentUser。并且发生该错误是因为您试图将该值作为一个字符串获取,而它是一个浮点数。要以正确且更简单的方式获取latitudelongitude,请使用以下代码行:

    String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference latlongRef = rootRef.child("Users").child(uid).child("latlong");
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            double latitude = dataSnapshot.child("latitude").getValue(Double.class);
            double longitude = dataSnapshot.child("longitude").getValue(Double.class);
            Log.d(TAG, latitude + ", " + longitude);
            setMarker(latitude, longitude);
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
        }
    };
    latlongRef.addListenerForSingleValueEvent(valueEventListener);
    

    logcat 中的输出将是:

    53,45, 9.14
    

    一旦您同时拥有latitudelongitude,您就可以调用一个方法将标记添加到地图中。

    【讨论】:

    • 非常感谢!它工作正常!现在我将尝试实时显示所有登录我的应用程序的用户的标记。你有什么建议吗?
    • 很高兴听到它有效:) 尝试显示所有登录用户的标记,基本上应该被视为另一个无法在评论中回答的问题。为了遵守本社区的规则,请使用MCVE 发布另一个新问题,以便我和其他 Firebase 开发人员可以帮助您。
    猜你喜欢
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 2012-03-09
    • 1970-01-01
    • 2018-07-06
    • 2020-07-03
    相关资源
    最近更新 更多