从 Firebase 获取具有唯一 ID 的子项的值
Posted
技术标签:
【中文标题】从 Firebase 获取具有唯一 ID 的子项的值【英文标题】:Getting the value of a child of a unique ID from Firebase 【发布时间】:2021-12-09 13:40:50 【问题描述】:我正在尝试从实时数据库中显示用户的当前位置,但它没有显示在地图上,数据库的结构如下:
"Blocked Users" :
"RCX2HZXIwlSmMHFgDytf1DgZBgi2" : 0
,
"User Location" :
"RCX2HZXIwlSmMHFgDytf1DgZBgi2" :
"latitude" : 37.4035483,
"longitude" : -122.097715
,
"Users" :
"RCX2HZXIwlSmMHFgDytf1DgZBgi2" :
"Alert Level" : "High",
"Emergency Type" : "Natural Disaster",
"address" : "Lapaz Tarlac",
"emergencyNum" : "0981232387346",
"name" : "Rafael Campos",
"phoneNum" : "0981233445675"
我在使用 onMapReady 中的代码从 Firebase 获取位置时遇到 NPE,我应该如何解决这个问题?
@Override
public void onMapReady(@NonNull GoogleMap googleMap)
mMap = googleMap;
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Users");
DatabaseReference uidRef = rootRef.child("User Location");
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);
LatLng location = new LatLng(latitude, longitude);
mMap.addMarker(new MarkerOptions().position(location).title(getCompleteAddress(latitude, longitude)));
mMap.moveCamera(CameraUpdateFactory.newLatLng(location));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location,14F));
Log.d("TAG", "latitude, longitude");
else
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
);
这是堆栈跟踪:
2021-10-23 11:19:19.139 12376-12376/com.example.rescuealertadmin E/androidRuntime: FATAL EXCEPTION: main
Process: com.example.rescuealertadmin, PID: 12376
java.lang.NullPointerException: Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference
at com.example.rescuealertadmin.RetrieveMapsActivity$4.onComplete(RetrieveMapsActivity.java:202)
at com.google.android.gms.tasks.zzi.run(com.google.android.gms:play-services-tasks@@17.2.1:1)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
【问题讨论】:
嘿拉斐尔。您已接受使用 100% 复制解决方案的答案。这不是你应该处理这种情况的方式。 嘿 Rafael,我可能复制了一个解决方案,但我已经在任何人之前回答了您的评论。 【参考方案1】:您收到以下错误:
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“double java.lang.Double.doubleValue()”
因为您在代码中使用了不正确的引用。如我所见,“纬度”和“经度”都是 UID 的直接子级。所以请更改以下代码行:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Users");
DatabaseReference uidRef = rootRef.child("User Location");
uidRef.get().addOnCompleteListener(/* ... /*);
收件人:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("User Location").child(uid);
uidRef.get().addOnCompleteListener(/* ... /*);
其余代码可能保持不变。
【讨论】:
【参考方案2】:您的User Location
路径有一个用户列表,因此您的onComplete
需要通过循环遍历结果来处理DataSnapshot
也有一个子节点列表的事实:
uidRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>()
@Override
public void onComplete(@NonNull Task<DataSnapshot> task)
if (task.isSuccessful())
DataSnapshot snapshot = task.getResult();
for (DataSnapshot child: snapshot.getChildren())
Double latitude = child.child("latitude").getValue(Double.class);
Double longitude = child.child("longitude").getValue(Double.class);
LatLng location = new LatLng(latitude, longitude);
...
);
【讨论】:
它仍然没有显示用户的位置,只是整个地图。 如果错误消息消失,此更改解决了您发布的问题。您可能还有其他问题,但这绝对是其中之一 - 也是导致错误消息的问题。为了进一步排除故障,我建议在onComplete
的第一行设置断点,并单步执行代码以查看您得到的值。【参考方案3】:
您在错误的节点上查找数据。
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Users");
这里您保存了用户信息
DatabaseReference uidRef = rootRef.child("User Location");
然后您将进一步进入“用户”节点。但是“用户”节点中没有“用户位置”。
如果你有 UID,你可以得到这样的数据
DatabaseReference uidRef = FirebaseDatabase.getInstance().getReference("User Location").child(UID);
【讨论】:
我已经修复了引用,但地图仍然没有显示用户的位置。【参考方案4】:您提供了错误的参考路径,这就是您获得 NPE 的原因。
转换自:
DatabaseReference rootRef =
FirebaseDatabase.getInstance().getReference("Users");
DatabaseReference uidRef = rootRef.child("User Location");
uidRef.get().addOnCompleteListener(/* ... /*);
到
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef =
FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("User Location").child(uid);
uidRef.get().addOnCompleteListener(//);
【讨论】:
我已经修复了引用,但地图仍然没有显示用户的位置。 你得到什么回应? 我尝试删除参考中的 '.child(uid)',标记出现,但它在 logcat 中显示'No setter/field for以上是关于从 Firebase 获取具有唯一 ID 的子项的值的主要内容,如果未能解决你的问题,请参考以下文章