当我从android中的Cloud Firestore获取数据时。它返回一个空变量。它应该返回标志值true或false。
public boolean checkIfUserAlreadyExists(final String email) {
final boolean[] flag = {false};
db.collection(context.getString(R.string.db_collection_users))
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
if (document.getData().get(context.getString(R.string.db_field_email)).toString() != null && document.getData().get(context.getString(R.string.db_field_email)).toString().equals(email)) {
Toast.makeText(context, "User Already exits", Toast.LENGTH_SHORT);
Log.e(TAG, "User already exists" + document.getData().get("email").toString());
flag[0] = true;
} else {
Log.e(TAG, "User do not exists");
}
}
} else {
Log.e(TAG, "Error getting documents.", task.getException());
}
}
});
return flag[0];
}
flag [0]应该返回true,但是在另一个活动中调用时它返回false。
答案 0 :(得分:1)
addOnCompleteListener
异步工作。
也就是说,您在设置flag[0]
之后立即返回OnCompleteListener
。到那时onComplete()
不会被调用,因此flag[0]
仍然具有初始值。该编译器预期会出现这种类型的错误,这就是为什么它警告您不能在回调方法内更改非最终变量的原因。但是您通过将其制成数组?
您可以通过多种方式解决此问题
代替返回值,而是从回调中访问值
public void checkIfUserAlreadyExists(final String email) {
db.collection(context.getString(R.string.db_collection_users))
.get()
.addOnCompleteListener(new OnCompleteListener < QuerySnapshot > () {
@Override
public void onComplete(@NonNull Task < QuerySnapshot > task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document: task.getResult()) {
if (document.getData().get(context.getString(R.string.db_field_email)).toString() != null && document.getData().get(context.getString(R.string.db_field_email)).toString().equals(email)) {
Toast.makeText(context, "User Already exits", Toast.LENGTH_SHORT);
Log.e(TAG, "User already exists" + document.getData().get("email").toString());
// User exists.
userTheResult(true);
return;
} else {
Log.e(TAG, "User do not exists");
}
}
// No user exists.
userTheResult(false);
} else {
Log.e(TAG, "Error getting documents.", task.getException());
}
}
});
}
您可以使用此类使线程等待直到获得结果。这样,您无需太多更改代码。您要做的就是简单地将类ThreadLockedTask<T>
添加到您的项目中,并按照给出的示例使用它。
import java.util.concurrent.atomic.AtomicReference;
/**
* @author Ahamad Anees P.A
* @version 1.0
* @param <T> type
*/
public class ThreadLockedTask<T> {
private AtomicReference<ResultWrapper<T>> mReference;
public ThreadLockedTask() {
mReference = new AtomicReference<>(new ResultWrapper<T>());
}
public T execute(Runnable runnable) {
runnable.run();
if (!mReference.get().mIsSet)
lockUntilSet();
return mReference.get().mResult;
}
private void lockUntilSet() {
synchronized (this) {
while (!mReference.get().isSet()) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public void setResult(T result) {
synchronized (this) {
ResultWrapper<T> wrapper = mReference.get();
wrapper.setResult(result);
wrapper.setIsSet(true);
notify();
}
}
public static class ResultWrapper<T> {
private boolean mIsSet;
private T mResult;
public boolean isSet() {
return mIsSet;
}
public T getResult() {
return mResult;
}
void setIsSet(boolean isCompleted) {
this.mIsSet = isCompleted;
}
void setResult(T result) {
this.mResult = result;
}
}
}
public boolean checkIfUserAlreadyExists(final String email) {
ThreadLockedTask < Boolean > task = new ThreadLockedTask < > ();
boolean flag = task.execute(new Runnable() {
@Override
public void run() {
db.collection(context.getString(R.string.db_collection_users))
.get()
.addOnCompleteListener(new OnCompleteListener < QuerySnapshot > () {
@Override
public void onComplete(@NonNull Task < QuerySnapshot > task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document: task.getResult()) {
if (document.getData().get(context.getString(R.string.db_field_email)).toString() != null && document.getData().get(context.getString(R.string.db_field_email)).toString().equals(email)) {
Toast.makeText(context, "User Already exits", Toast.LENGTH_SHORT);
Log.e(TAG, "User already exists" + document.getData().get("email").toString());
task.setResult(true);
return;
} else {
Log.e(TAG, "User do not exists");
}
}
} else {
Log.e(TAG, "Error getting documents.", task.getException());
}
task.setResult(false);
}
});
}
});
return flag;
}