我有一些全局变量,其值需要根据数据库所包含的内容进行动态更新。
所以我尝试使用ValueEventListener()
我可以成功读取预期值并将其显示在日志中。
但是不幸的是,当我尝试将该值存储在先前声明的某些全局变量中时,尽管它没有显示任何错误,但是它无法工作,但是却无法存储预期的值(我给代码where,您可以通过ValueEventListener()
找到更新后显示列表大小的日志消息,其输出仍显示0。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private String RxuserId;
private String currentuserName;
private String currentuser,path;
public ArrayList<String> mToken;
private FirebaseDatabase database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//for keeping the keyboard hidden
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Intent intent=getIntent();
RxuserId=intent.getStringExtra("Id");
Rxusrnm=intent.getStringExtra("Name");
//storeName(usrnm);
currentuserName=SharedPrefManager.getmInstnce(this).getUsername();
currentuser=SharedPrefManager.getmInstnce(this).getUserID();
database = FirebaseDatabase.getInstance();
providers = new ArrayList<>();
mToken = new ArrayList<>();
if(RxuserId!=null){
database.getReference().child("users").child(RxuserId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mToken.add(dataSnapshot.child("fcm token").getValue().toString());
mToken.add("nsks");
Toast.makeText(getApplicationContext(),"REQUIRED TOKRN "+dataSnapshot.child("fcm token").getValue().toString(),Toast.LENGTH_LONG).show();
Log.d(TAG,"REQUIRED TOKRN "+dataSnapshot.child("fcm token").getValue().toString());
//These two are shown correctly
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
Log.d(TAG,"REQUIRED TOKRN "+mToken.size())//which shows 0 ;
}
我在哪里做错了?我应该怎么做才能从ValueEventListener()
内部更新全局变量的值?
谢谢
答案 0 :(得分:0)
Firebase的 ValueEventListener 适用于asynchronously。这就是为什么您的日志记录代码在结束时比异步侦听器被触发更早打印的原因。实际上,firebase中的数据确实已添加(反映)到全局变量中,但在日志之后。
如果要在Firebase数据更改时执行一些逻辑,则应直接在ValueEventListener内部执行逻辑,或使用 LiveData 或 RxJava 。
如何使用LiveData:
// User is model class
List<User> users = new ArrayList<>();
final MutableLiveData<List<User>> data = new MutableLiveData<>();
database.child("users").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<User> users = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
User user = ds.getValue(User.class);
users.add(user);
}
data.setValue(users); // data can be observed later
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
这对于LivaData来说不是很有用。通常,当使用firebse的逻辑在另一个类中(在存储库MVVM中)时,将使用LiveData来根据数据更改来更改UI。
用户列表可以这样存储:
offsets.topic.replication.factor