Java 为什么transaction.update命令在carrelloatale.prodotti.add()命令之前执行

Java 为什么transaction.update命令在carrelloatale.prodotti.add()命令之前执行,java,android,google-cloud-firestore,Java,Android,Google Cloud Firestore,我正在尝试从CloudFireStore的文档中获取产品,然后将该产品放入购物车。当我读取(成功地)产品时,我尝试将其放入一个在外部声明的arraylist中,但除非我将final放入变量,否则它不会工作。 这样,当我运行下面的代码时,我成功地检索到了数据,但是操作carreloatuale.prodotti.add(prod)是在命令transaction.update()之后执行的,因此更新不会从开始上传任何内容 //prendo l'utente Fireb

我正在尝试从CloudFireStore的文档中获取产品,然后将该产品放入购物车。当我读取(成功地)产品时,我尝试将其放入一个在外部声明的arraylist中,但除非我将final放入变量,否则它不会工作。 这样,当我运行下面的代码时,我成功地检索到了数据,但是操作carreloatuale.prodotti.add(prod)是在命令transaction.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);
                            }
                        });
//prendo l'tente
FirebaseAuth auth=FirebaseAuth.getInstance();
//我是斯坎内里扎托生产商
最终字符串codiceprodottotscannerizzato=String.valueOf(intentData);
final FirebaseFirestore db=FirebaseFirestore.getInstance();
最终文档参考docRef=db.collection(“carrelli”).document(auth.getUid());
最终文件参考docrefprodotti=db.集合(“prodotti”).文件(CODICEPRODOTTOSCANNERIZATO);
db.runTransaction(new Transaction.Function(){
@凌驾
public Void apply(事务处理)引发FirebaseFirestoreException{
DocumentSnapshot snapshot=transaction.get(docRef);
final Carrello carrellottuale=snapshot.toObject(Carrello.class);
docrefprodotti.get().addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
DocumentSnapshot document=task.getResult();
if(document.exists()){
Prodotti prod=document.toObject(Prodotti.class);
prod.id=codiceProdottoScannerizzato;
prod.totalePezziCarrello=1;
carrellottuale.prodotti.add(prod);
Log.d(标记“PRODOTTO:+prod.toString());
}否则{
日志d(标签“无此类文件”);
}
}否则{
Log.d(标记“get failed with”,task.getException());
}
}
});
Log.d(标记为“carrellofb:+carrelloAttuale.size());
transaction.update(docRef,“prodotti”,carrellottuale.getProdotti());
//成功
返回null;
}
}).addOnSuccessListener(新的OnSuccessListener(){
@凌驾
成功时公开作废(作废避免){
Log.d(标记“事务成功!”);
}
})
.addOnFailureListener(新的OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常e){
Log.w(标记“事务失败”,e);
}
});
我希望命令更新在carreloattuale.prodotti.add(prod)之后执行 在调试日志中,标记的顺序为: 卡雷罗FB:0 PRODOTTO:Nome:latte

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

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


有关更多信息,我建议您查看我的anwser的最后一部分,我已经在其中解释了如何使用自定义回调来完成。您还可以查看此以更好地理解。

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

这意味着任何需要数据中的数据的代码都必须在
onComplete
方法中,或者从那里调用。比如:

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());
    }
});
docrefprodotti.get().addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
DocumentSnapshot document=task.getResult();
if(document.exists()){
Prodotti prod=document.toObject(Prodotti.class);
prod.id=codiceProdottoScannerizzato;
prod.totalePezziCarrello=1;
carrellottuale.prodotti.add(prod);
Log.d(标记“PRODOTTO:+prod.toString());
}否则{
日志d(标签“无此类文件”);
}
}否则{
Log.d(标记“get failed with”,task.getException());
}
Log.d(标记为“carrellofb:+carrelloAttuale.size());
transaction.update(docRef,“prodotti”,carrellottuale.getProdotti());
}
});