【问题标题】:Return single value from Firebase从 Firebase 返回单个值
【发布时间】:2018-02-19 20:56:50
【问题描述】:
当我想从 Firebase 数据库获取值并从方法返回值时遇到问题。
我知道它是异步的,onDataChange 是在方法“返回”值之后执行的,我发现很多主题都有这个问题,但我找不到我必须做什么才能返回它。
这是我的简单方法:
private int getScore(String word) {
Log.e("DTAG", "order 1");
String userId = getFirebaseUserId();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Words").child(word).child(userId).child("score");
rootRef.addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
oldScore = Integer.parseInt(dataSnapshot.getValue().toString());
Log.e("DTAG", "order 3");
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
Log.e("DTAG", "order 2");
return oldScore;
}
【问题讨论】:
标签:
java
android
firebase
firebase-realtime-database
【解决方案1】:
既然你知道它是异步的,那意味着你不知道它什么时候会完成。
解决它的几种方法是:
- 回调(最简单,不需要库)
- 事件总线
- 可观察
第一个选项回调:
您可以创建自己的回调,例如:
interface OnCompletion {
onComplete(object: Object)
onFailure(message: String)
}
然后你在你的方法中使用那个回调:
private void getFromDb(String word, completion: onCompletion){
Log.e("DTAG", "order 1");
String userId = getFirebaseUserId();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Words").child(word).child(userId).child("score");
rootRef.addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
completion.onComplete('Pass something');
}
@Override
public void onCancelled(DatabaseError databaseError) {
completion.onFailure('Pass something');
}
});
}
那你这样称呼它:
getFromDb("test", new OnCompletion() {
onComplete(object: Object) {
//Cast it and access the data here
}
onFailure(message: String) {
//access the data here
}
}
){
【解决方案2】:
试试这个。
private void getFromDb(String word){
Log.e("DTAG", "order 1");
String userId = getFirebaseUserId();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Words").child(word).child(userId).child("score");
rootRef.addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
getScore(Integer.parseInt(dataSnapshot.getValue().toString()));
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private int getScore(int score){
Log.v("score",String.valueOf(score);
return score
}