从 Firebase 检索位置并将标记放在谷歌地图上

Posted

技术标签:

【中文标题】从 Firebase 检索位置并将标记放在谷歌地图上【英文标题】:Retrieve location from Firebase and put marker on google map 【发布时间】:2020-07-03 05:24:03 【问题描述】:

我在 Firebase 中创建了数据库并尝试在地图中显示标记。还是行不通。我该怎么办。应用程序运行,但当地图活动打开时,应用程序关闭。我手动创建数据库。我提到了这个链接:-Retrieve location from Firebase and put marker on google map api for android

这是代码

地图活动

ma​​p.java

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.lang.reflect.Array;
import java.util.EventListener;

public class map extends FragmentActivity implements OnMapReadyCallback 

     FirebaseDatabase mDatabase;
     DatabaseReference mDatabaseReference;
     String nameddd;
    private GoogleMap mMap;

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

        nameddd = FirebaseDatabase.getInstance().getReference("Location").child("Name").toString();
        mDatabase = FirebaseDatabase.getInstance();
        mDatabaseReference = mDatabase.getReference("Location");
    
    @Override
    public void onMapReady(GoogleMap googleMap) 
        mMap = googleMap;

        mDatabaseReference.addChildEventListener(new ChildEventListener() 
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) 
                LatLng newLocation = new LatLng(dataSnapshot.child("Latitude").getValue(Long.class),dataSnapshot.child("Longitude").getValue(Long.class));
                mMap.addMarker(new MarkerOptions().position(newLocation).title(nameddd)
                );
            

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

            

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) 

            

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

            

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) 

            
        );
    

这是 Firebase 数据库结构

Location
   |-2JHHhnUhYKVzAmoDvrhtUJfhGEg2
         |- ABpos: "20"
         |- Latitude: "12"
         |- Longitude: "22"
         |- Name: "Sion"

日志猫

Process: com.bloodapp.blood, PID: 5393
    com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to long
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertLong(com.google.firebase:firebase-database@@19.2.1:384)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToPrimitive(com.google.firebase:firebase-database@@19.2.1:295)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@19.2.1:214)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database@@19.2.1:79)
        at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database@@19.2.1:203)
        at com.bloodapp.blood.map$1.onChildAdded(map.java:54)
        at com.google.firebase.database.core.ChildEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.2.1:79)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.2.1:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.2.1:55)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

【问题讨论】:

数据库中存储的所有值都是字符串格式 如果应用程序崩溃,会有一个堆栈跟踪。请在 logcat 上查找,并将其添加到您的问题中。也请回复@AlexMamo @AlexMamo 我添加了 logcat 条目。 map.java 是地图类 【参考方案1】:

您收到以下错误:

com.google.firebase.database.DatabaseException:无法将 java.lang.String 类型的值转换为 long

因为您试图将Latitude 属性的值作为Long 获取:

dataSnapshot.child("Latitude").getValue(Long.class)

在您的数据库中存储为字符串。

|- Longitude: "22"

看到等式标记了吗?

要解决这个问题,您应该将数据库中 LatitudeLongitude 属性的类型更改为 double 类型和 not 字符串:

|- Longitude: 22.01

并相应地获取它们:

double lat = dataSnapshot.child("Latitude").getValue(Double.class)

经纬度不能是long数字,应该是double,因为两者都包含小数。

【讨论】:

【参考方案2】:
    @Override
public void onMapReady(GoogleMap googleMap) 
    mMap = googleMap;
    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference locationsRef = rootRef.child("childName");
    final GeoFire geoFire = new GeoFire(locationsRef);
        geoFire.getLocation("DataKey", new LocationCallback() 
            @Override
            public void onLocationResult(String key, GeoLocation location) 
                double lat =location.latitude;
                double lng =location.longitude;
                LatLng sydney = new LatLng(lng, lat);
                mMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.defaultMarker(HUE_BLUE)).position(sydney).title("car"));
                Toast.makeText(getApplicationContext(),""+sydney,Toast.LENGTH_SHORT).show();
                mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
                mMap.animateCamera(CameraUpdateFactory.zoomTo(9));
            

            @Override
            public void onCancelled(DatabaseError databaseError) 

            
        );
    

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


【讨论】:

以上是关于从 Firebase 检索位置并将标记放在谷歌地图上的主要内容,如果未能解决你的问题,请参考以下文章

如何从 GeoFire 中检索持续更新的位置数据并将其放在 Google 地图上?

如何在谷歌地图android上设置多个标记?

如何在flutter中将标记从firebase(真实数据库)检索到新的google maps api

即使在代码中手动设置位置后,标记也不会显示在地图上

触发谷歌地图标记点击

谷歌地图 API V3 - 完全相同的位置上的多个标记