android - 如何在按钮的 onClickListener 中从实时数据库中获取数据
问题描述
我正在构建一个应用程序并尝试在用户按下按钮后立即获取数据。然而,数据获取部分直到 onClickListener 的 onComplete 结束后才会发生。我需要在 onComplete 结束之前访问数据。
现在,我的片段包含一个电子邮件和密码字段,他们填写并按下“登录”按钮。我在调用方法onClickListener
的登录按钮上设置了一个。FirebaseAuth's
signInWithEmailandPassword
这将返回一个 AuthResult 任务,我将它设置为一个 onCompleteListener。
如果此任务成功,我会触发一个addListenerForSingleValueEvent()
任务以从 Firebase 实时数据库中获取相关用户的数据。似乎此任务在 onComplete 方法之后运行。我该如何改变呢?我尝试为此使用 AsyncTask,但结果是一样的。
我的登录片段:
mLogInButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
String email = mEmailText.getText().toString();
String password = mPasswordText.getText().toString();
final boolean[] loginSuccess = {false};
Task task = mViewModel.signIn(email,
password).addOnCompleteListener
(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithEmail:success");
Toast.makeText(getActivity(),
"Signed in!",
Toast.LENGTH_SHORT).show();
loginSuccess[0] = true;
String uid = mViewModel.getAuth().getUid();
mViewModel.fetchUser(uid);
Log.d(TAG, mViewModel.getUser().getName());
} else {
Log.w(TAG, "signInWithEmail:failure",
task.getException());
Toast.makeText(getActivity(), "Auth failed.
Check log!",
Toast.LENGTH_SHORT).show();
loginSuccess[0] = false;
}
}
});
//Task fetchDatabase = task.addOnCompleteListener(new
//OnCompleteListener() {
//@Override
//public void onComplete(@NonNull Task task) {
// Log.d(TAG, "After!");
// }
//});
// updateUIWithDatabaseDetails(mView);
}
});
我的 fetchUser(uid) 及其关联的 ValueEventListener:
public void fetchUser(String uid) {
mUserDatabase.child(uid).addListenerForSingleValueEvent(userDataValueListener);
}
public ValueEventListener userDataValueListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Log.d(TAG, "User exists in remote!");
mUser = dataSnapshot.getValue(User.class);
}
else {
Log.d(TAG, "user doesn't exist.");
mUser = null;
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, "Can't fetch Firebase Database user:" + databaseError.getMessage());
mUser = null;
}
};
当前设置立即崩溃并出现 NullPointerException,Log.d(TAG, mViewModel.getUser().getName());
因为数据库尚未获取用户并更新 SharedViewModel 中的用户。
底线:我认为数据库获取任务会在登录的 onClick 上的 onComplete 结束后排队执行。在 onComplete 运行时,我有什么办法可以挤进这个任务?我正在考虑使用 Handler 将其从 UI 线程中移出,但我并不真正理解它,并且确实需要一些指针。
任何帮助,将不胜感激!
解决方案
推荐阅读
- r - R如何将具有递归滞后的for循环转换为函数?
- javascript - 保存页面上关于艺术家的 Ajax 调用数据,但仅针对特定艺术家保存一次
- autodesk-forge - Autodesk Forge® 模型衍生 API:转换为 svf2 错误 406“此设计不支持 SVF2。”
- flutter - Flutter:显示来自 API 提供商的 YouTube 视频
- assembly - 在 Arm 7 中浏览数组
- html - 我可以阻止浏览器在更改密码对话框中建议存储的密码吗?
- python - ZeroMQ 连接器如何检查订单是否已被 SL/TP 关闭?
- google-apps-script - Google 表格脚本 - 在同一个电子表格中将不同的数据从一张表格复制到另一张表格
- python - types.MappingProxyType 的类型提示
- laravel - 如何通过 laravel 8 中的数据透视表从另一个表中获取数据?