我需要从他们的UID中检索Firebase数据库中的用户名。这是我执行此操作的代码,但我无法弄清楚如何使其正常工作。该主题来自:
final String[] returnName = new String[1];
立即:
return returnName[0].toString();
不等待它首先从侦听器填充数据,因此返回值为null并且应用程序崩溃。以下是此模块的完整代码:
private synchronized String getFriendName(String key) {
final String[] returnName = new String[1];
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Profiles").child(key).child("Name");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String userResult = datas.getKey();
if (userResult != null) {
returnName[0] = dataSnapshot.getValue().toString();
String temp = dataSnapshot.getValue().toString();
Toast.makeText(getBaseContext(), "Step 1: " + temp, Toast.LENGTH_SHORT).show();
Toast.makeText(getBaseContext(), "Step 2: " + returnName[0], Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return returnName[0].toString();
}
我花了几个小时阅读并尝试使用它来实现这个功能,但是我无法在启动返回值之前先让代码实际执行正确。
任何人都可以帮助我吗?
@TaherKorshidi 这是调用此函数的代码:
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(currentLocation.latitude, currentLocation.longitude), radius);
geoQuery.removeAllListeners();
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
friendID = key;
String friend = getFriendName(friendID);
}
}
回答,@ TaherKorshidi的答案是在同一个监听器中获取其他值。没有别的方法可以解决这个问题,直到你把我指向这个方向,我才能确定怎么做。工作解决方案:
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
getFriendKey = key;
if (getFriendKey != ping_userID) {
for(ContactsList d : UserList){
if(d.getUID() != null && d.getUID().contains(getFriendKey)) {
friendName = d.getName();
}
}
Toast.makeText(getBaseContext(), "Name: " + String.valueOf(friendName), Toast.LENGTH_SHORT).show();
getFriendLocation(getFriendKey, friendName);
}
}
答案 0 :(得分:1)
您可以将asyncTask用于此目的,如下所示
public static class GetFriendName extends AsyncTask<String, Void, Void>{
String returnName;
@Override
protected void onPreExecute() {
super.onPreExecute();
//Show progress bar
}
@Override
protected Void doInBackground(String... strings) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Profiles").child(key).child("Name");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String userResult = datas.getKey();
if (userResult != null) {
returnName = dataSnapshot.getValue().toString();
String temp = dataSnapshot.getValue().toString();
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//Dismiss progress bar
showFriendName(returnName);
}
}
您可以从onCreate()调用此类,如下所示
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(currentLocation.latitude, currentLocation.longitude), radius);
geoQuery.removeAllListeners();
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
friendID = key;
new GetFriendName().execute(friendID);
}
}
然后你可以使用这种方法将你的friendName分配给一个字符串值并在那里工作
private static void showFriendName(String friendName){
Toast.makeText(stackOverflowActivity, ""+friendName, Toast.LENGTH_SHORT).show();
String friend = friendName;
//Do your work here
}
此方法是从onPostExecute()调用的。
答案 1 :(得分:0)
一种方法是使用CountDownLatch
类:
private synchronized String getFriendName(String key) {
final String[] returnName = new String[1];
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Profiles").child(key).child("Name");
final CountDownLatch latch = new CountDownLatch(1);
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String userResult = datas.getKey();
if (userResult != null) {
returnName[0] = dataSnapshot.getValue().toString();
String temp = dataSnapshot.getValue().toString();
Toast.makeText(getBaseContext(), "Step 1: " + temp, Toast.LENGTH_SHORT).show();
Toast.makeText(getBaseContext(), "Step 2: " + returnName[0], Toast.LENGTH_SHORT).show();
latch.countDown();
}
}
latch.countDown();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnName[0].toString();
}
虽然它解决了你的问题,但它不是一个好的解决方案。