问题不是由多线程引起的,而是由Firebase异步加载数据引起的。等到您的
updateUI函数查看的值时
aa,
onComplete尚未运行。
通过放置一些放置良好的日志记录语句,这最容易看到:
System.out.println("Before attaching listener");docRef.get().addonCompleteListener(new OnCompleteListener<documentSnapshot>() { @Override public void onComplete(@NonNull Task<documentSnapshot> task) { System.out.println("Got document"); }});System.out.println("After attaching listener");当您运行此代码时,它会打印
附加监听器之前
附加监听器后
得到文件
这可能不是您所期望的,但恰恰说明了检查
aa时为什么未修改的原因
updateUI。该文件尚未从Firestore中读取,因此
onComplete尚未运行。
此解决方案是移动从数据库中需要的数据的所有码 成 的
onComplete方法。在这种情况下,最简单的方法是:
public void userExists(String uid) { FirebaseFirestore db = FirebaseFirestore.getInstance(); documentReference docRef = db.collection("users").document(uid); docRef.get().addonCompleteListener(new OnCompleteListener<documentSnapshot>() { @Override public void onComplete(@NonNull Task<documentSnapshot> task) { if (task.isSuccessful()) { documentSnapshot documentSnapshot = task.getResult(); if (documentSnapshot.exists()) { //Fill layout with the user data and the user linked document data //USER DATA txvNombre=findViewById(R.id.nombrePerfil); txvNombre.setText(user.getDisplayName()); imvAvatar=findViewById(R.id.imvVistaPerfilAvatar); Picasso.with(VistaPerfilActivity.this) .load(user.getPhotoUrl()) .resize(500,500) .centerCrop() .into(imvAvatar); //HERE GOES THE document DATA } } } });}现在,需要文档的代码仅在文档实际可用后才运行。这将起作用,但是确实会使该
userExists函数的可重用性降低。如果要解决此问题,可以将回调传递
到
userExists该回调中,然后在加载文档后调用该回调。
public interface UserExistsCallback { void onCallback(boolean isExisting);}并将其
userExists用作:
public void userExists(String uid, final UserExistsCallback callback) { FirebaseFirestore db = FirebaseFirestore.getInstance(); documentReference docRef = db.collection("users").document(uid); docRef.get().addonCompleteListener(new OnCompleteListener<documentSnapshot>() { @Override public void onComplete(@NonNull Task<documentSnapshot> task) { boolean userExists = false; if (task.isSuccessful()) { documentSnapshot documentSnapshot = task.getResult(); userExists = documentSnapshot.exists(); } callback.onCallback(userExists); } });}然后使用以下命令调用它
updateUI:
if (user != null) { userExists(user.getUid(), new UserExistsCallback() { public void onCallback(boolean isExisting) { if(isExisting){ //Fill layout with the user data and the user linked document data //USER DATA txvNombre=findViewById(R.id.nombrePerfil); txvNombre.setText(user.getDisplayName()); imvAvatar=findViewById(R.id.imvVistaPerfilAvatar); Picasso.with(VistaPerfilActivity.this) .load(user.getPhotoUrl()) .resize(500,500) .centerCrop() .into(imvAvatar); //HERE GOES THE document DATA }else{ } } else { finish(); } });}如您所见,我们的
`回调与OnCompleteListener`Firestore本身非常相似,它只是针对我们的需求量身定制了。



