【问题标题】:firestore onSuccess listener isn't workingfirestore onSuccess 监听器不起作用
【发布时间】:2018-12-28 18:10:14
【问题描述】:

我正在尝试从我的数据库中下载一些测验对象。 下面的函数是从某个activity的onCreate中调用的。

 private void downloadQuizzesFromCloud(){

        String user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
        final FirebaseFirestore db = FirebaseFirestore.getInstance();
        String user_quizzes_path = "users/".concat(user_id).concat("/quizzes");
        Query userQuizzes = db.collection(user_quizzes_path);

        userQuizzes.get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            quizzes.clear();
                            for (QueryDocumentSnapshot document : task.getResult()) {

                                Quiz quizDownloaded = getQuizFromCloud(document.getId());
                                quizzes.add(quizDownloaded);
                            }
                            Toast.makeText(QuizzesActivity.this,"downloaded to list ".concat(String.valueOf(quizzes.size()).concat("  quizzes")), Toast.LENGTH_SHORT).show();
                            //TODO put in recycle adapter
                        } else { }
                    }
                });

    }

(user_quizzes_path 包含存储在云上的测验对象集合的正确路径)

我调试了这个函数,发现命令后:

 userQuizzes.get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>()

函数完成执行,即不检查和执行 onComplete 的情况,只是跳过所有这些代码。

我试图在 firebase 的文档中找到它,但没有找到任何东西。 为什么会发生这种情况,我该如何解决?

在此不胜感激,谢谢!

【问题讨论】:

    标签: android firebase google-cloud-firestore


    【解决方案1】:

    从 Firestore 服务器完成读取操作后,将调用 onComplete。如果它没有被调用,我可以看到两个可能的原因:

    1. 您没有连接到服务器。除非您之前读取过数据(并且它位于 Firestore 客户端维护的本地数据库中),否则这意味着读取永远不会在本地完成。
    2. 您没有异步思考。请注意,数据是从服务器异步读取的,在您调用get()onComplete 触发之间可能有一段时间。要测试是否是这种情况,请在if (task.isSuccessful()) { 上放置一个断点并在调试器中运行该应用程序。从服务器读取数据时将触发断点。

    【讨论】:

    • 谢谢,问题确实是因为我没有异步思考。如何确保我在代码中更改的对象只有在服务器数据读取完成后才会更改?
    • 您可以通过从onComplete 中调用代码来实现这一点,因为这是在数据加载后触发的方法。
    • 这会起作用,但是如果我要在我的代码中的其他地方使用变量“quizzes”(例如,就在函数“downloadQuizzesFromCloud”完成之前)不能保证任务已经完成我可能在“测验”变量中有不正确的数据。有没有办法解决这个问题?
    • 任何依赖于从数据库异步加载的测验的代码都应该在onComplete 内(在数据加载时调用)或从该方法内调用。我在这里对你之前的问题发表了同样的评论:stackoverflow.com/questions/53970276/…
    【解决方案2】:

    使用回调接口。就像下面这样。

    private void downloadQuizzesFromCloud(Consumer listener) {
    
        String user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
    
        final FirebaseFirestore db = FirebaseFirestore.getInstance();
    
        String user_quizzes_path = "users/".concat(user_id).concat("/quizzes");
    
        Query userQuizzes = db.collection(user_quizzes_path);
    
        userQuizzes.get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            List<Quiz> quizzes = new ArrayList<>();
                            for (QueryDocumentSnapshot document : task.getResult()) {
                                Quiz quizDownloaded = getQuizFromCloud(document.getId());
                                quizzes.add(quizDownloaded);
                            }
                            listener.onGet(quizzes);
                            Toast.makeText(QuizzesActivity.this,"downloaded to list ".concat(String.valueOf(quizzes.size()).concat("  quizzes")), Toast.LENGTH_SHORT).show();
                            //TODO put in recycle adapter
                        } else { }
                    }
                });
    
     } 
     interface Consumer {
        void onGet(List<Quiz> quizzes);
     }
    

    【讨论】:

    • 我想要达到这样的效果:downloadQuizzesFromCloud();打印(测验);我希望当我打印它们时会更新测验。如何使用回调接口做到这一点?
    • 调用downloadQuizzesFromCloud(this::print)并声明一个函数private void print(List&lt;Quiz&gt; quizzes) { // do everything here. }。如果您使用的是 JAVA-7,请执行以下操作,downloadQuizzesFromCloud(this) 并实现 onGet(List&lt;Quiz&gt; quizzes) 函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    相关资源
    最近更新 更多