我正在开发的项目在firebase实时数据库中有3个“表”,即:
用户(包含用户的登录信息,例如电子邮件,密码移动电话号码等)
VictimProfiles(包含基本个人资料信息,如个人资料照片字符串,姓名,职位和用户表中相应的用户ID)
VolunteerProfiles(包含地址,纬度,经度,可用性时间以及相应的UserID和VictimProfileID(Firebase生成的那些))
在我的Google地图活动中,我需要在每个志愿者的位置以及当前使用该应用的用户上放置标记,并在自定义信息窗口中显示志愿者的必要信息, 但是,如下面的代码所示,当我尝试从志愿者表的ValueEventListener中访问VictimProfile和Users表时,他们的数据不会被写入我正在写入的公共字符串中。我知道这听起来很复杂,但看看代码,你会明白我的意思
public void DropVolunteerMarkers()
{
//DROP ALL MARKERS FUNCTION
volunteerDatabaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot volunteerprofile:dataSnapshot.getChildren())
{
key=(String) volunteerprofile.child("UserID").getValue();
victimID=(String) volunteerprofile.child("VictimProfileID").getValue();
getVictimInfo();//GET NAME,PIC,JOB TITLE FROM THE VICTIM TABLE FOR THIS SPECIFIC VOLUNTEER
getUserInfo();//GET EMAIL AND PHONE NUMBER FROM USERS TABLE FOR THIS SPECIFIC VOLUNTEER
String currentuserid=SaveSharedPreference.getUserName(FindNearbyVolunteers.this);
if(!key.equals(currentuserid))//TO AVOID CURRENT USER BEING SHOWN AS A VOLUNTEER
{
address= (String)volunteerprofile.child("Address").getValue();
availabiliity=(String)volunteerprofile.child("Availability").getValue();
String LAT= (String) volunteerprofile.child("Latitude").getValue();
String LNG= (String) volunteerprofile.child("Longitude").getValue();
Toast.makeText(FindNearbyVolunteers.this,LAT+", "+LNG,Toast.LENGTH_SHORT).show();
Double Lat= Double.parseDouble(LAT);
Double Long= Double.parseDouble(LNG);
LatLng latLng = new LatLng(Lat,Long);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
Toast.makeText(FindNearbyVolunteers.this,key+", "+victimID+", "+name+", "+jobtitle+", "+availabiliity+", "+email+", "+address,Toast.LENGTH_LONG).show();
//mMap.setInfoWindowAdapter(new VolunteerPopupAdapter(FindNearbyVolunteers.this,name,jobtitle,availabiliity,email,address,dp,number));
markerOptions.title(volunteerprofile.getKey().toString());
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mCurrLocationMarker = mMap.addMarker(markerOptions);
}
else{
//IN CASE OF CURRENT USER
//Place current location marker
LatLng latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("YOU");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
mCurrLocationMarker = mMap.addMarker(markerOptions);
}}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
getVictimInfo()方法:
private void getVictimInfo()
{
victimDatabaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot victimProfile:dataSnapshot.getChildren())
{
if(victimProfile.getKey().equals(victimID))
{
dp=(String)victimProfile.child("DP").getValue();
jobtitle=(String)victimProfile.child("JobTitle").getValue();
name=(String)victimProfile.child("Name").getValue();
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
getUserInfo()方法
private void getUserInfo(){
userDatabaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot userProfile:dataSnapshot.getChildren())
{
if(userProfile.getKey().equals(key))
{
email=(String)userProfile.child("Email").getValue();
number=(String)userProfile.child("Mobile").getValue();;
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
我应该保存值的字符串
DatabaseReference volunteerDatabaseReference,userDatabaseReference,victimDatabaseReference;
String dp,jobtitle="no value",name="no value";
String email="no value",number="no value",address="no value",availabiliity="no value",victimID,key;
我的数据库截图 enter image description here
答案 0 :(得分:0)
您现在还无法使用尚未加载的内容。换句话说,您不能简单地将keyVaultResourceId
,dp
和jobtitle
声明为全局变量,并在email
方法之外使用它们,因为它始终为onDataChange()
到期此方法的异步行为。这意味着,当您尝试在该方法之外使用这些值时,数据尚未从数据库中完成加载,这就是为什么无法访问,并且您总是得到null
这就是你的数据库中没有写任何内容的原因。
这个问题的快速解决方法是仅在null
方法中使用所有这些值,或者如果你想在外面使用它们,我建议你深入到异步世界,看看我的anwser的最后一部分从这个 post 中我已经解释了如何使用自定义回调来完成它。您还可以查看此 video ,以便更好地理解。