Я выполняю код, аналогичный проблеме в в этом вопросе , за исключением того, что я выбираю массивы из каждого документа и добавляю их элементы в глобальный ArrayList. После этого, вне collection.get()
, я выполняю операцию с этим массивом и возвращаюсь. Однако, если я записываю глобальный размер ArrayList из прослушивателя onSuccess, он дает правильный ответ, но если я делаю это за пределами collection.get (), он всегда дает 0. Моя проблема заключается в том, что я не могу вернуться изнутри onSuccess, потому что это не вернет всю мою функцию, и поэтому мне нужно сделать это после collection.get (), где ArrayList не был заполнен, предположительно, так как операция get () возвращает Task<>
, что является асинхронная операция и поэтому она не ожидает завершения. Вот мой код:
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;
}
EDIT:
Я пытаюсь сделать это с помощью обратного вызова, который выглядит так:
// 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 () я хочу вернуть правильное допустимое значение после завершения обратного вызова, поскольку в настоящее время оно возвращает неправильное значение до завершения обратного вызова.