这是我的代码:
public ArrayList<Integer> getArray() {
final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myReff =database.getReference("server").child("user");
myReff.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
boolean connected = dataSnapshot.getValue(Boolean.class);
if (connected){
Log.d("CONNECT","YES");
}
else {
Log.d("CONNECT","NO");
}
GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
array = dataSnapshot.getValue(genericTypeIndicator) ;
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return array;
}
这是我的数据库:
"server" : {
"user" : {
1 : 0,
2 : 0,
3 : 0
},
}
此代码的目的是检索数据库中的数组。
问题是 OnDataChange在此函数中永远不会被称为
(我调试我的代码,在其中放置断点,但没有发生。并且Logcat中没有显示CONNECT)。
我不明白为什么,因为当添加一个监听器时,即使数据没有改变,也必须至少触发一次ondatachange。
你能解释一下为什么没有执行OnDataChange吗?
答案 0 :(得分:1)
当您添加ListenerForSingleValueEvent
或任何其他Firebase-listener时,您的手机会启动连接到互联网的服务并在获得结果后返回结果。
当您的手机连接到firebase服务器并返回数据时,您的功能(public ArrayList<Integer> getArray()
)已经完成。该函数不会等待数据返回,它会继续。
最终,当您的数据从Firebase数据库返回时,它会调用函数public void onDataChange(DataSnapshot dataSnapshot)
或您在function public void onCancelled(DatabaseError databaseError)
new ValueEventListener(){}
因此,在您的情况下,如果要返回数组,则需要从onDataChange(DataSnapshot dataSnapshot)
函数调用另一个函数并将该数组作为参数传递。
例如:
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
boolean connected = dataSnapshot.getValue(Boolean.class);
if (connected){
Log.d("CONNECT","YES");
}
else {
Log.d("CONNECT","NO");
}
GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
array = dataSnapshot.getValue(genericTypeIndicator);
handleArrayFunction(array);
}
在你的public ArrayList<Integer> getArray()
函数之外声明一个像这样的新函数:
private void handleArrayFunction(ArrayList<Integer> array){
//use your array for what you want
}
希望我能理解! 如果某些事情不够明确,请随意这样说:)
答案 1 :(得分:0)
我昨天想知道同样的问题, 看看这段代码片段如何解决问题。
逻辑是,有一些数据及其变更(更新或删除) onDataChanged 将被触发。但是当最初没有数据时,它将转到 onError 。
请检查代码段,我想你会找到答案。
@Override
public void onDataChanged() {
// If there are no chat messages, show a view that invites the user to add a message.
mBinder.progress.setVisibility(View.GONE); // tried to hide progressbar on data changed when there is no data found but didn't worked.
mBinder.rvChatUsersList.llNoData.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
@Override
public void onError(@NonNull DatabaseError error) {
super.onError(error);
mBinder.progress.setVisibility(View.GONE); // tried to hide progressbar on error due to no data found and it worked.
}
答案 2 :(得分:-1)
Just write it.
public ArrayList<Integer> getArray() {
final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myReff =database.getReference("server").child("user");
myReff.addValueEventListener
(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
boolean connected = dataSnapshot.getValue(Boolean.class);
if (connected){
Log.d("CONNECT","YES");
}
else {
Log.d("CONNECT","NO");
}
GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
array = dataSnapshot.getValue(genericTypeIndicator) ;
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return array;
}