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