【问题标题】:Returning value after Firestore collection.get() has finished the operationFirestore collection.get() 完成操作后返回值
【发布时间】:2018-10-18 16:52:08
【问题描述】:

我正在运行与this question 中的问题类似的代码,除了我从每个文档中获取数组并将它们的元素添加到全局 ArrayList 中。之后,在collection.get() 之外,我对该数组执行操作并返回。但是,如果我从 onSuccess 侦听器中记录全局 ArrayList 大小,它会给出正确的答案,但如果我在 collection.get() 之外这样做,它总是给出 0。我的问题是我无法从内部返回onSuccess 因为这不会为我的整个函数返回,所以我需要在未填充 ArrayList 的 collection.get() 之后执行它,大概是因为 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;
 }

编辑:
我正在尝试使用如下回调来执行此操作:

// 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() 中,我想在回调完成后返回正确的有效值,因为它当前在回调完成之前返回了不正确的值。

【问题讨论】:

  • 您似乎知道自己需要做什么 - 仅使用回调中 get 的结果,或从使用结果的回调中启动其他工作。
  • @DougStevenson 我的问题是我无法从回调中返回,因为它只返回 onSuccess,而不是 Validator。如果我在回调之外使用变量,我会得到错误的值。
  • 请检查副本以了解发生这种情况的原因以及如何使用自定义回调解决此问题。
  • 您不应该从回调中返回值。只需调用另一个方法并将结果从回调传递给它。

标签: android firebase google-cloud-firestore


【解决方案1】:

我首先使用@AlexMamo 的解决方案here 解决了我的问题,然后使用此解决方案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
                }
            }
        });

【讨论】:

    猜你喜欢
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 2018-06-21
    相关资源
    最近更新 更多