【问题标题】:Unable to retrieve user location data from Firebase with unique key无法使用唯一键从 Firebase 检索用户位置数据
【发布时间】:2021-12-02 16:21:20
【问题描述】:

我已成功地在 Firebase 中为我的数据库架构添加了一个唯一键,而不是使用 push(),以防止它在位置刷新时生成新的推送键。

{
  "Users" : {
    "RCX2HZXIwlSmMHFgDytf1DgZBgi2" : {
      "Alert Level" : "High",
      "Emergency Type" : "Natural Disaster",
      "User Location" : {
        "latitude" : 15.5352917,
        "longitude" : 120.7742867
      },
      "address" : "Lapaz Tarlac",
      "emergencyNum" : "0981232387346",
      "name" : "Rafael Campos",
      "phoneNum" : "0981233445675"
    }
  }
}

我检查了从 Realtime Databse 检索位置的另一个应用程序,但用户的位置根本没有反映在地图上。我一直在代码中配置数据库引用以获取用户位置的正确路径,但应用程序不断从 NullPointerExceptions 崩溃。我应该如何引用正确的子键,尤其是用户的唯一键?

private GoogleMap mMap;
private ActivityRetrieveMapsBinding binding;
private Location mLocation;
private LocationManager mLocationManager;
private LocationRequest mLocationRequest;
private com.google.android.gms.location.LocationListener listener;
private LocationManager locationManager;
GoogleApiClient mGoogleApiClient;
public static final int REQUEST_CHECK_SETTINGS = 1001;
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    binding = ActivityRetrieveMapsBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

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

    mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    checkLocation();
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) this)
                .addOnConnectionFailedListener((GoogleApiClient.OnConnectionFailedListener) this)
                .addApi(LocationServices.API)
                .build();
    }

    mGoogleApiClient.connect();

    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(mLocationRequest);

    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {

            final Status status = locationSettingsResult.getStatus();
            final LocationSettingsStates LS_state = locationSettingsResult.getLocationSettingsStates();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    // All location settings are satisfied. The client can initialize location
                    // requests here.

                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied. But could be fixed by showing the user
                    // a dialog.
                    try {
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        status.startResolutionForResult(RetrieveMapsActivity.this, REQUEST_CHECK_SETTINGS);

                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way to fix the
                    // settings so we won't show the dialog.

                    break;
            }
        }
    });
}

private boolean checkLocation() {

    if(!isLocationEnabled()){
        showAlert();
    }
    return isLocationEnabled();

}



private void showAlert() {
    final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
    dialog.setTitle("Enable Location")
            .setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
                    "use this app")
            .setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {

                    Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivity(myIntent);
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {

                }
            });
    dialog.show();
}

private boolean isLocationEnabled() {

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
            locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference locationRef = rootRef.child("Users").child(uid).child("User Location");

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference locationRef = rootRef.child("Users").child(uid).child("User Location");

    locationRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DataSnapshot> task) {
            if (task.isSuccessful()){
                DataSnapshot dataSnapshot = task.getResult();
                double latitude = dataSnapshot.child("latitude").getValue(Double.class);
                double longitude = dataSnapshot.child("longitude").getValue(Double.class);
                LatLng location = new LatLng(latitude, longitude);
                Log.d("Tag", "latitude, longitude");
                mMap.addMarker(new MarkerOptions().position(location).title(getCompleteAddress(latitude, longitude)));
                mMap.moveCamera(CameraUpdateFactory.newLatLng(location));
                mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location,14F));
            }
            else {
                Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
            }
        }
    });


}



private String getCompleteAddress(double Latitude,double Longitude){

    String address = "";

    Geocoder geocoder = new Geocoder(RetrieveMapsActivity.this, Locale.getDefault());

    try{

        List<Address> addresses = geocoder.getFromLocation(Latitude,Longitude,1);

        if(address!=null){

            Address returnAddress = addresses.get(0);
            StringBuilder stringBuilderReturnAddress =  new StringBuilder("");

            for(int i=0; i<=returnAddress.getMaxAddressLineIndex();i++){
                stringBuilderReturnAddress.append(returnAddress.getAddressLine(i)).append("\n");
            }

            address = stringBuilderReturnAddress.toString();

        }
        else{
            Toast.makeText(this, "Address not found", Toast.LENGTH_SHORT).show();
        }

    }
    catch (Exception e){
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }


    return address;
}


@Override
public void onLocationChanged(@NonNull Location location) {

}

@Override
public void onConnected(@Nullable Bundle bundle) {

}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
    if (requestCode == REQUEST_CHECK_SETTINGS) {
        switch (resultCode) {
            case Activity.RESULT_OK:
                // All required changes were successfully made

                break;
            case Activity.RESULT_CANCELED:
                // The user was asked to change settings but chose not to

                break;
            default:
                break;
        }
    }
}

}

编辑:我已经按照 Alex 的规定添加了更改后的代码:

    @Override
    public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    DatabaseReference rootRef = 
    FirebaseDatabase.getInstance().getReference();
    DatabaseReference locationRef = 
    rootRef.child("Users").child(uid).child("User Location");

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference locationRef = rootRef.child("Users").child(uid).child("User Location");

    locationRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DataSnapshot> task) {
            if (task.isSuccessful()){
                DataSnapshot dataSnapshot = task.getResult();
                double latitude = dataSnapshot.child("latitude").getValue(Double.class);
                double longitude = dataSnapshot.child("longitude").getValue(Double.class);
                LatLng location = new LatLng(latitude, longitude);
                Log.d("Tag", "latitude, longitude");
                mMap.addMarker(new MarkerOptions().position(location).title(getCompleteAddress(latitude, longitude)));
                mMap.moveCamera(CameraUpdateFactory.newLatLng(location));
                mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location,14F));
            }
            else {
                Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
            }
        }
    });


}

我仍然没有看到用户的当前位置被反映并且出现以下错误:

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“double java.lang.Double.doubleValue()” 在 com.example.rescuealertadmin.RetrieveMapsActivity$4.onComplete(RetrieveMapsActivity.java:194) 在 com.google.android.gms.tasks.zzj.run(com.google.android.gms:play-services-tasks@@17.2.0:4) 在 android.os.Handler.handleCallback(Handler.java:938) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:223) 在 android.app.ActivityThread.main(ActivityThread.java:7656) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

【问题讨论】:

    标签: java android firebase firebase-realtime-database google-cloud-platform


    【解决方案1】:

    使用以下参考时:

    String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference uidRef = rootRef.child("Users").child(uid).child("User Location");
    

    请注意,无需循环遍历结果。您应该只在DataSnapshot 对象上再次调用.child(),如以下代码行所示:

    uidRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DataSnapshot> task) {
            if (task.isSuccessful()) {
                DataSnapshot snapshot = task.getResult();
                double latitude = snapshot.child("latitude").getValue(Double.class);
                double longitude = snapshot.child("longitude").getValue(Double.class);
                Log.d("TAG", "latitude, longitude");
            } else {
                Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
            }
        }
    });
    

    logcat 中的结果将是:

    15.44318, 120.7148767
    

    【讨论】:

    • 只要确定一下,这一切都在 OnMapReady() 中,对吧?
    • 是的,在同一个地方你已经拥有它。试一试,告诉我它是否有效。
    • 我仍然在使用 NullPointerException 的代码时遇到错误
    • “我仍然有错误”没有提供足够的信息,所以我可以提供进一步的帮助。请编辑您的问题并添加更改后的代码,以便我查看。我亲自测试了这段代码,它确实有效。
    • 我已经添加了修改后的代码。它仍然没有反映用户在地图上的当前位置。
    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 2018-03-03
    相关资源
    最近更新 更多