gpt4 book ai didi

android - 使用方法返回值调用 firebase Firestore 时无法获取变量中的数据

转载 作者:行者123 更新时间:2023-11-29 00:53:39 25 4
gpt4 key购买 nike

当我在 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,但在另一个 Activity 中调用时返回 false。

最佳答案

addOnCompleteListener异步工作。

那是你回来了flag[0]OnCompleteListener 之后立即已设置。到那时 onComplete()不会打电话,因此 flag[0]仍然有初始值。该编译器预料到了这种类型的错误,这就是为什么它会警告您不能在回调方法中更改非最终变量。但是你通过将它变成一个数组以一种奇怪的方式绕过了它😀

你可以通过多种方式解决这个问题


解决方案1

不返回值,而是从回调中访问值

illustration

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());
}
}
});
}


解决方案2

您可以使用此类使线程等待直到获得结果。这样您就不必对代码进行太多更改。您所要做的只是添加类 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;
}

关于android - 使用方法返回值调用 firebase Firestore 时无法获取变量中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57010013/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com