当前位置: 首页 > 知识库问答 >
问题:

为什么命令会执行事务。更新是在carrelloatale之前执行的。普罗多蒂。add()命令

严宸
2023-03-14

我正试图从cloud firestore的文档中获取产品,然后将该产品放入购物车。当我阅读(成功地)产品时,我会尝试将其放入一个在外部声明的arraylist中,但除非我将final放入变量,否则它不会工作。这样,当我运行下面的代码时,我成功地检索到了数据,但操作仍在进行。普罗多蒂。add(prod)在命令事务之后执行。update(),因此更新不会从一开始就上传任何内容。

//prendo l'utente
                FirebaseAuth auth= FirebaseAuth.getInstance();

                //mi salvo il codice del prodotto scannerizzato
                final String codiceProdottoScannerizzato=String.valueOf(intentData);
                final FirebaseFirestore db = FirebaseFirestore.getInstance();
                final DocumentReference docRef = db.collection("carrelli").document(auth.getUid());
                final DocumentReference docrefprodotti = db.collection("prodotti").document(codiceProdottoScannerizzato);
                db.runTransaction(new Transaction.Function<Void>() {
                    @Override
                    public Void apply(Transaction transaction) throws FirebaseFirestoreException {
                        DocumentSnapshot snapshot = transaction.get(docRef);
                        final Carrello carrelloAttuale = snapshot.toObject(Carrello.class);

                        docrefprodotti.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                            @Override
                            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                                if (task.isSuccessful()) {
                                    DocumentSnapshot document = task.getResult();
                                    if (document.exists()) {
                                        Prodotti prod=document.toObject(Prodotti.class);
                                        prod.id=codiceProdottoScannerizzato;
                                        prod.totalePezziCarrello=1;
                                        carrelloAttuale.prodotti.add(prod);
                                        Log.d(TAG, "PRODOTTO: " + prod.toString());
                                    } else {
                                        Log.d(TAG, "No such document");

                                    }
                                } else {
                                    Log.d(TAG, "get failed with ", task.getException());
                                }
                            }
                        });

                        Log.d(TAG, "CARRELLO FB: " + carrelloAttuale.size());
                        transaction.update(docRef, "prodotti", carrelloAttuale.getProdotti());

                        // Success
                        return null;
                    }
                }).addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        Log.d(TAG, "Transaction success!");
                    }
                })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.w(TAG, "Transaction failure.", e);
                            }
                        });

我希望命令更新是在carrelloatale之后执行的。普罗多蒂。在调试日志中添加(prod)标签的顺序是:CARRELLO FB:0 PRODOTTO:Nome:latte

共有2个答案

房光临
2023-03-14

“命令更新”在调用“carrellottuale.prodotti.add(prod)”之前执行,因为onComplete()方法具有异步行为并立即返回。这意味着在数据库更新操作完成后的一段时间内,侦听器才会被调用。无法保证需要多长时间。根据连接速度和状态,更新操作可能需要几百毫秒到几秒钟的时间才能完成。

如果要对该数据使用某些逻辑,必须等待异步Firebase数据库操作完成。这意味着您只能在侦听器回调本身中使用prod对象。

关于更多的信息,我建议你看看我在这篇文章中回答的最后一部分,我在其中解释了如何使用自定义回调来完成。你也可以看看这个视频来更好地理解。

荣波
2023-03-14

数据从Firestore异步加载,因为可能必须从服务器检索数据。为了防止阻塞应用程序,在检索数据时,主代码将继续。然后,当数据可用时,就会调用您的onComplete

这意味着任何需要数据中的数据的代码都必须在on完成方法中,或者从那里被调用。所以类似于:

docrefprodotti.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            if (document.exists()) {
                Prodotti prod=document.toObject(Prodotti.class);
                prod.id=codiceProdottoScannerizzato;
                prod.totalePezziCarrello=1;
                carrelloAttuale.prodotti.add(prod);
                Log.d(TAG, "PRODOTTO: " + prod.toString());
            } else {
                Log.d(TAG, "No such document");

            }
        } else {
            Log.d(TAG, "get failed with ", task.getException());
        }

        Log.d(TAG, "CARRELLO FB: " + carrelloAttuale.size());
        transaction.update(docRef, "prodotti", carrelloAttuale.getProdotti());
    }
});

另见:

  • 如何作为方法的结果返回DocumentSnapShot
 类似资料:
  • 问题内容: 问题在标题中。以感叹号开头的shell命令(shell脚本的一部分)的目的是什么?具体示例: 在foo.sh中: 我知道没有空格,感叹号用于替换历史记录,并且根据手册页可用于评估“ expr为false时为True ”。但是在示例上下文中,这对我来说没有意义。 问题答案: TL; DR:这只是绕过您使用它的特定行中的标志。 在hek2mgl的正确和有用的答案中添加add 。 你有: B

  • 问题内容: 我有一个Excel文件,我想更新工作表中的多行。所以我写了这段代码: 我得到这个错误: 查询表达式’id = 1更新[Data14City $]中的语法错误(缺少运算符),设置B_1_1 = 0,B_1_2 = 8,B_1_3 = 17,B_1_4 = 0,其中id = 2’。 当我添加到此行时: 我收到此错误: SQL语句结束后找到的字符。 如何在Excel中执行多条语句? 谢谢 问

  • 如果你希望在每次运行 Puppet 之前执行命令,可以在配置文件中使用 prerun_command 配置。 类似地,你也可以使用 postrun_command 配置运行 Puppet 之后需要执行的命令。 这种机制为 Puppet 与其他软件的集成提供了强大的钩子,甚至可以触发其他机器上的事件。 prerun 和 postrun 命令必须能成功运行(即其返回的状态码为 0),否则 Puppet

  • 本文向大家介绍通过什么命令查找执行命令?相关面试题,主要包含被问及通过什么命令查找执行命令?时的应答技巧和注意事项,需要的朋友参考一下 答案: which 只能查可执行文件 whereis 只能查二进制文件、说明文档,源文件等  

  • telnet 6379命令是怎么执行的?

  • 修改项目配置 'url_model' => 3, # cd 到项目www目录下 # php index.php index user b 1 以上指令表示控制器为Index的user方法,可以通过$_GET['b']获取参数值