getGeoPoint() 方法 returns 调用时为空。 Firebase 集合中有超过 1 个文档
getGeoPoint() method returns null when called. There is more than 1 document in the Firebase collection
我正在学习构建聊天室应用程序的教程,该应用程序包括 用户位置 功能和 Google 地图 API,但是,我正在学习它只是为了学习如何使用 Google 地图 API,我正在尝试构建一个可以记录旅行路线并按日期访问它们的跟踪应用程序等
有一个 UserLocation
对象,由 地理位置、时间戳和用户对象 组成,它的实例存储在 Firestore 集合中。数据库工作正常:
但是,在验证后我收到以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.trackingapp, PID: 13386
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.firestore.GeoPoint com.example.trackingapp.models.UserLocation.getGeo_point()' on a null object reference
at com.example.trackingapp.ui.MainActivity.setCameraView(MainActivity.java:109)
at com.example.trackingapp.ui.MainActivity.onMapReady(MainActivity.java:410)
at com.google.android.gms.maps.zzac.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzaq.dispatchTransaction(Unknown Source)
at com.google.android.gms.internal.maps.zzb.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:499)
at ds.b(:com.google.android.gms.dynamite_mapsdynamite@203615052@20.36.15 (040700-0):2)
at com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.dynamite_mapsdynamite@203615052@20.36.15 (040700-0):2)
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)
我猜我在尝试将原始应用程序的逻辑实施到我的应用程序中时犯了一个错误。
我几乎可以肯定问题出在 mUserListEventListener
的使用方式上。这个变量实际上包含了将 UserLocations 放入 ArrayList 的所有逻辑,但它只在 OnDestroy( )方法!!
教程的源码就是这样写的,mUserListEventListener
没有其他用法。我已尝试在其他地方实现 UserLocations 逻辑,但我做不对。
这里是相关的MainActivity代码。这是我应用程序中唯一的 activity(除了登录和注册):
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
// Variables Google Maps
private boolean mLocationPermissionGranted = false;
private MapView mMapView;
private FusedLocationProviderClient mFusedLocationClient;
private UserLocation mUserLocation;
private ArrayList<UserLocation> mUserLocations = new ArrayList<>();
private GoogleMap mGoogleMap;
private LatLngBounds mMapBoundary;
private UserLocation mUserPosition;
// Variables Firebase
private FirebaseFirestore mDb;
private ListenerRegistration mUserListEventListener;
private Set<String> mUserIds = new HashSet<>();
// Otras Variables
private RecyclerView rvUsers;
private UserRecyclerAdapter adapter;
private ArrayList<User> mUserList = new ArrayList<>();
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initGoogleMap(savedInstanceState);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
// DATA DE FIREBASE
//
mDb = FirebaseFirestore.getInstance();
rvUsers = (RecyclerView) findViewById(R.id.user_list_recycler_view);
getUsers();
initUserRecyclerView();
setUserPosition();
}
private void setCameraView(){
double bottomBoundary = mUserPosition.getGeo_point().getLatitude() - .1;
double leftBoundary = mUserPosition.getGeo_point().getLongitude() - .1;
double topBoundary = mUserPosition.getGeo_point().getLatitude() + .1;
double rightBoundary = mUserPosition.getGeo_point().getLongitude() + .1;
mMapBoundary = new LatLngBounds(
new LatLng(bottomBoundary,leftBoundary),
new LatLng(topBoundary,rightBoundary)
);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mMapBoundary,0));
}
private void setUserPosition(){
for (UserLocation userLocation : mUserLocations){
if (userLocation.getUser().getUser_id().equals(FirebaseAuth.getInstance().getUid())){
mUserPosition = userLocation;
}
}
}
private void getUserDetails(){
if (mUserLocation == null){
mUserLocation = new UserLocation();
DocumentReference userRef = mDb.collection("Users")
.document(Objects.requireNonNull(FirebaseAuth.getInstance().getUid()));
userRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()){
Log.d(TAG, "onComplete: successfully set the user details.");
User user = task.getResult().toObject(User.class);
mUserLocation.setUser(user);
((UserClient)getApplicationContext()).setUser(user);
getLastKnownLocation();
}
}
});
}
else {
getLastKnownLocation();
}
}
private void saveUserLocation(){
if(mUserLocation != null){
DocumentReference locationRef = mDb.
collection("User Locations")
.document(Objects.requireNonNull(FirebaseAuth.getInstance().getUid()));
locationRef.set(mUserLocation).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
Log.d(TAG, "saveUserLocation: \ninserted user location into database." +
"\n latitude: " + mUserLocation.getGeo_point().getLatitude() +
"\n longitude: " + mUserLocation.getGeo_point().getLongitude());
}
}
});
}
}
private void getLastKnownLocation() {
Log.d(TAG, "getLastKnownLocation: called");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mFusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful()){
Location location = task.getResult();
GeoPoint geoPoint = new GeoPoint(location.getLatitude(), location.getLongitude());
Log.d(TAG, "onComplete: latitude: " + geoPoint.getLatitude());
Log.d(TAG, "onComplete: longitude" + geoPoint.getLongitude());
mUserLocation.setGeo_point(geoPoint);
mUserLocation.setTimestamp(null);
saveUserLocation();
}
}
});
}
private void getUsers() {
CollectionReference usersCollection = mDb
.collection("Users");
mUserListEventListener = usersCollection.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
Log.d(TAG, "onEvent: called.");
if (e != null) {
Log.e(TAG, "onEvent: Listen failed.", e);
return;
}
if(queryDocumentSnapshots != null){
// Clear the list and add all the users again
mUserList.clear();
mUserList = new ArrayList<>();
for (QueryDocumentSnapshot doc : queryDocumentSnapshots) {
User user = doc.toObject(User.class);
mUserList.add(user);
getUserLocation(user);
}
Log.d(TAG, "onEvent: user list size: " + mUserList.size());
}
}
});
}
private void getUserLocation(User user){
DocumentReference locationRef = mDb.collection("User Locations")
.document(user.getUser_id() );
locationRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()){
if(task.getResult().toObject(UserLocation.class) != null){
mUserLocations.add(task.getResult().toObject(UserLocation.class));
}
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if (checkMapServices()) {
if (mLocationPermissionGranted) {
getUsers();
getUserDetails();
} else {
getLocationPermission();
}
}
mMapView.onResume();
}
@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}
@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
map.setMyLocationEnabled(true);
mGoogleMap = map;
setCameraView();
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
if(mUserListEventListener != null){
mUserListEventListener.remove();
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
具有 NullPointerException
与返回 null 不同。
在这种情况下,如错误跟踪所示,在此处:
at com.example.trackingapp.ui.MainActivity.setCameraView(MainActivity.java:109)
调用了一个空对象。
java.lang.NullPointerException: Attempt to invoke virtual method
'com.google.firebase.firestore.GeoPoint
com.example.trackingapp.models.UserLocation.getGeo_point()'
on a null object reference
这里是mUserPosition.getGeo_point()
。
报错提示mUserPosition
为空,需要先初始化
如果 var mUserPosition
为 null,可能(我不知道)你需要调用 getUserDetails
。
if (mUserPosition == null) {
getUserDetails();
}
我正在学习构建聊天室应用程序的教程,该应用程序包括 用户位置 功能和 Google 地图 API,但是,我正在学习它只是为了学习如何使用 Google 地图 API,我正在尝试构建一个可以记录旅行路线并按日期访问它们的跟踪应用程序等
有一个 UserLocation
对象,由 地理位置、时间戳和用户对象 组成,它的实例存储在 Firestore 集合中。数据库工作正常:
但是,在验证后我收到以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.trackingapp, PID: 13386
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.firestore.GeoPoint com.example.trackingapp.models.UserLocation.getGeo_point()' on a null object reference
at com.example.trackingapp.ui.MainActivity.setCameraView(MainActivity.java:109)
at com.example.trackingapp.ui.MainActivity.onMapReady(MainActivity.java:410)
at com.google.android.gms.maps.zzac.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzaq.dispatchTransaction(Unknown Source)
at com.google.android.gms.internal.maps.zzb.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:499)
at ds.b(:com.google.android.gms.dynamite_mapsdynamite@203615052@20.36.15 (040700-0):2)
at com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.dynamite_mapsdynamite@203615052@20.36.15 (040700-0):2)
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)
我猜我在尝试将原始应用程序的逻辑实施到我的应用程序中时犯了一个错误。
我几乎可以肯定问题出在 mUserListEventListener
的使用方式上。这个变量实际上包含了将 UserLocations 放入 ArrayList 的所有逻辑,但它只在 OnDestroy( )方法!!
教程的源码就是这样写的,mUserListEventListener
没有其他用法。我已尝试在其他地方实现 UserLocations 逻辑,但我做不对。
这里是相关的MainActivity代码。这是我应用程序中唯一的 activity(除了登录和注册):
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
// Variables Google Maps
private boolean mLocationPermissionGranted = false;
private MapView mMapView;
private FusedLocationProviderClient mFusedLocationClient;
private UserLocation mUserLocation;
private ArrayList<UserLocation> mUserLocations = new ArrayList<>();
private GoogleMap mGoogleMap;
private LatLngBounds mMapBoundary;
private UserLocation mUserPosition;
// Variables Firebase
private FirebaseFirestore mDb;
private ListenerRegistration mUserListEventListener;
private Set<String> mUserIds = new HashSet<>();
// Otras Variables
private RecyclerView rvUsers;
private UserRecyclerAdapter adapter;
private ArrayList<User> mUserList = new ArrayList<>();
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initGoogleMap(savedInstanceState);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
// DATA DE FIREBASE
//
mDb = FirebaseFirestore.getInstance();
rvUsers = (RecyclerView) findViewById(R.id.user_list_recycler_view);
getUsers();
initUserRecyclerView();
setUserPosition();
}
private void setCameraView(){
double bottomBoundary = mUserPosition.getGeo_point().getLatitude() - .1;
double leftBoundary = mUserPosition.getGeo_point().getLongitude() - .1;
double topBoundary = mUserPosition.getGeo_point().getLatitude() + .1;
double rightBoundary = mUserPosition.getGeo_point().getLongitude() + .1;
mMapBoundary = new LatLngBounds(
new LatLng(bottomBoundary,leftBoundary),
new LatLng(topBoundary,rightBoundary)
);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mMapBoundary,0));
}
private void setUserPosition(){
for (UserLocation userLocation : mUserLocations){
if (userLocation.getUser().getUser_id().equals(FirebaseAuth.getInstance().getUid())){
mUserPosition = userLocation;
}
}
}
private void getUserDetails(){
if (mUserLocation == null){
mUserLocation = new UserLocation();
DocumentReference userRef = mDb.collection("Users")
.document(Objects.requireNonNull(FirebaseAuth.getInstance().getUid()));
userRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()){
Log.d(TAG, "onComplete: successfully set the user details.");
User user = task.getResult().toObject(User.class);
mUserLocation.setUser(user);
((UserClient)getApplicationContext()).setUser(user);
getLastKnownLocation();
}
}
});
}
else {
getLastKnownLocation();
}
}
private void saveUserLocation(){
if(mUserLocation != null){
DocumentReference locationRef = mDb.
collection("User Locations")
.document(Objects.requireNonNull(FirebaseAuth.getInstance().getUid()));
locationRef.set(mUserLocation).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
Log.d(TAG, "saveUserLocation: \ninserted user location into database." +
"\n latitude: " + mUserLocation.getGeo_point().getLatitude() +
"\n longitude: " + mUserLocation.getGeo_point().getLongitude());
}
}
});
}
}
private void getLastKnownLocation() {
Log.d(TAG, "getLastKnownLocation: called");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mFusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful()){
Location location = task.getResult();
GeoPoint geoPoint = new GeoPoint(location.getLatitude(), location.getLongitude());
Log.d(TAG, "onComplete: latitude: " + geoPoint.getLatitude());
Log.d(TAG, "onComplete: longitude" + geoPoint.getLongitude());
mUserLocation.setGeo_point(geoPoint);
mUserLocation.setTimestamp(null);
saveUserLocation();
}
}
});
}
private void getUsers() {
CollectionReference usersCollection = mDb
.collection("Users");
mUserListEventListener = usersCollection.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
Log.d(TAG, "onEvent: called.");
if (e != null) {
Log.e(TAG, "onEvent: Listen failed.", e);
return;
}
if(queryDocumentSnapshots != null){
// Clear the list and add all the users again
mUserList.clear();
mUserList = new ArrayList<>();
for (QueryDocumentSnapshot doc : queryDocumentSnapshots) {
User user = doc.toObject(User.class);
mUserList.add(user);
getUserLocation(user);
}
Log.d(TAG, "onEvent: user list size: " + mUserList.size());
}
}
});
}
private void getUserLocation(User user){
DocumentReference locationRef = mDb.collection("User Locations")
.document(user.getUser_id() );
locationRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()){
if(task.getResult().toObject(UserLocation.class) != null){
mUserLocations.add(task.getResult().toObject(UserLocation.class));
}
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if (checkMapServices()) {
if (mLocationPermissionGranted) {
getUsers();
getUserDetails();
} else {
getLocationPermission();
}
}
mMapView.onResume();
}
@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}
@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
map.setMyLocationEnabled(true);
mGoogleMap = map;
setCameraView();
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
if(mUserListEventListener != null){
mUserListEventListener.remove();
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
具有 NullPointerException
与返回 null 不同。
在这种情况下,如错误跟踪所示,在此处:
at com.example.trackingapp.ui.MainActivity.setCameraView(MainActivity.java:109)
调用了一个空对象。
java.lang.NullPointerException: Attempt to invoke virtual method
'com.google.firebase.firestore.GeoPoint
com.example.trackingapp.models.UserLocation.getGeo_point()'
on a null object reference
这里是mUserPosition.getGeo_point()
。
报错提示mUserPosition
为空,需要先初始化
如果 var mUserPosition
为 null,可能(我不知道)你需要调用 getUserDetails
。
if (mUserPosition == null) {
getUserDetails();
}