getGeoPoint() 方法在调用时返回 null。 Firebase 集合中有超过 1 个文档
Posted
技术标签:
【中文标题】getGeoPoint() 方法在调用时返回 null。 Firebase 集合中有超过 1 个文档【英文标题】:getGeoPoint() method returns null when called. There is more than 1 document in the Firebase collection 【发布时间】:2021-01-21 22:55:06 【问题描述】:我正在关注有关使用 Google Maps API 构建包含 用户位置 功能的 Chatroom 应用程序的教程,但是,我关注它只是为了学习如何使用 Google Maps 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)
我猜我在尝试将原始 App 的逻辑实现到我的时犯了一个错误。
我几乎可以肯定问题在于mUserListEventListener
的使用方式。这个变量实际上包含了将 UserLocations 放入 ArrayList 的所有逻辑,但它只在 OnDestroy() 方法中调用!!
教程的源代码就是这样写的,mUserListEventListener
没有其他用法。我已经尝试在其他地方实现 UserLocations 逻辑,但我无法做到。
这里是相关的 MainActivity 代码。这是我的应用程序中唯一的活动(除了登录和注册):
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();
【问题讨论】:
【参考方案1】:拥有NullPointerException
与返回 null 不同。
在这种情况下,如错误跟踪所示,在这里:
at com.example.trackingapp.ui.MainActivity.setCameraView(MainActivity.java:109)
调用了一个空 obj。
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
为null,需要先初始化。
如果 var mUserPosition
为空,您可能需要调用 getUserDetails
(这我不知道)。
if (mUserPosition == null)
getUserDetails();
【讨论】:
以上是关于getGeoPoint() 方法在调用时返回 null。 Firebase 集合中有超过 1 个文档的主要内容,如果未能解决你的问题,请参考以下文章
为啥 UITableViewCells cellForRowAt 方法不调用?
opencv调用nu-book/zxing-cpp识别二维码