Firestore collection.get()完成操作后返回值
我正在运行类似于此问题中的问题的代码,我正在从每个文档中获取数组,并将其元素添加到全局ArrayList中.之后,在 collection.get()
之外,我对该数组执行操作并返回.但是,如果我从onSuccess侦听器内Log.d全局ArrayList大小,它给出了正确的答案,但是如果我在collection.get()之外这样做,它总是给出0.我的问题是我不能从内部返回onSuccess,因为这不会为我的整个函数返回,因此我需要在未填充ArrayList的collection.get()之后执行此操作,大概是因为get()操作返回了 Task<>
这是一个异步操作,因此它不必等待它完成.这是我的代码:
I am running code similar to the problem in this question except, I am fetching arrays from each document and adding their elements to a global ArrayList. After that, outside of the collection.get()
, I perform an operation on that array and return. However, If I Log.d the global ArrayList size from within the onSuccess listener, it gives the correct answer but if I do so outside of the collection.get() it always gives 0. My problem is that I cannot return from within the onSuccess because this will not return for my whole function and so I need to do it after the collection.get() where the ArrayList has not been populate, presumably since the get() operation returns a Task<>
which is an asynchronous operation and so it doesn't wait for it to complete. Here is my code:
public static boolean Validator(final String sometext) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
final ArrayList<String> mArrayList = new ArrayList<>();
db.collection("my_collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if (queryDocumentSnapshots.isEmpty()) {
Log.d(TAG, "Validator onSuccess: LIST EMPTY");
return;
} else {
// Convert the Query Snapshot to a list of Document Snapshots, in this
// case, one document for each my_collection
List<DocumentSnapshot> my_collections = queryDocumentSnapshots.getDocuments();
for (int i = 0; i < my_collections.size(); i++) {
ArrayList<String> mArrayitems = (ArrayList<String>) my_collections.get(i).get("array");
for (int j = 0; j < mArrayitems.size(); j++) {
Log.d(TAG, "Adding array: " + mArrayitems.get(j).toString());
mArrayList.add(mArrayitems.get(j).toString());
}
}
Log.d(TAG, "Validator onSuccess: array list built");
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "Validator onFailure: " + e);
}
});
// check if the given sometext matches a array in the list
Log.d(TAG, "array list size: " + mArrayList.size());
if (mArrayList.size() > 0) {
for (int i = 0; i < mArrayList.size(); i++) {
if (sometext.endsWith(mArrayList.get(i))) {
return true
}
}
}
return false;
}
我正在尝试通过一个类似于以下内容的回调来做到这一点:
I'm trying to do this with a callback which looks like:
// constructor
public Validator(String sometext) {
this.valid = false;
this.sometext = sometext
}
public interface myCallback{
void onCallback(boolean valid);
}
public boolean validate() {
readData(new MyCallback() {
@Override
public void onCallback(boolean valid) {
setValid(valid);
}
});
return this.valid;
}
private void readData(final MyCallback myCallback) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("my_collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if (queryDocumentSnapshots.isEmpty()) {
Log.d(TAG, "Validator onSuccess: LIST EMPTY");
} else {
List<DocumentSnapshot> my_collections = queryDocumentSnapshots.getDocuments();
ArrayList<String> mArrayList = new ArrayList<>();
for (int i = 0; i < my_collections.size(); i++) {
ArrayList<String> mArrayItems = (ArrayList<String>) my_collections.get(i).get("array");
for (int j = 0; j < mArrayItems.size(); j++) {
Log.d(TAG, "Adding array: " + mArrayItems.get(j).toString());
mArrayList.add(mArrayItems.get(j).toString());
}
}
boolean result = false;
Log.d(TAG, "array list size: " + mArrayList.size());
if (mArrayList.size() > 0) {
for (int i = 0; i < mArrayList.size(); i++) {
if (sometext.endsWith(mArrayList.get(i))) {
result = true;
Log.d(TAG, "MATCH FOUND");
break;
}
}
}
myCallback.onCallback(result);
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "Validator onFailure: " + e);
}
});
}
我遇到的问题是在validate()中,我想在回调完成后返回正确的有效值,因为它当前在回调完成之前返回了不正确的值.
The problem I'm having is that in validate() I want to return the correct valid value after the callback is finished because it currently returns the incorrect value before the callback has finished.
我能够通过使用@AlexMamo的解决方案此处.
I was able to solve my issue by first using @AlexMamo's solution here and then listen for the valid variable being changed by using this solution here.
public class ValidatorVariable {
private boolean valid;
private ChangeListener listener;
public boolean isValid(){
return valid;
}
public void setValid(boolean valid){
this.valid = valid;
if (listener != null) listener.onChange();
}
public ChangeListener getListener(){
return listener;
}
public void setListener(ChangeListener listener){
this.listener = listener;
}
public interface ChangeListener {
void onChange();
}
}
用于:
ValidatorVariable vv = new ValidatorVariable();
vv.setListener(new ValidatorVariable.ChangeListener() {
@Override
public void onChange() {
if (vv.isValid()){
// do stuf
}
}
});