我正在尝试从云 Firestore 的文档中获取产品,然后将该产品放入购物车。当我(成功)读取产品时,我尝试将其放入在外部声明的数组列表中,但除非我将 Final 放入变量,否则它不起作用。 这样做,当我运行下面的代码时,我成功检索了数据,但是操作 carrelloAttuale.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);
}
});
我希望命令更新在 carrelloAttuale.prodotti.add(prod) 之后执行 在调试日志中,标签的顺序是: 卡雷罗 FB:0 产品名称:拿铁
最佳答案
数据是从 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());
}
});
另请参阅:
关于java - 为什么命令 transaction.update 在 carrelloAttuale.prodotti.add() 命令之前执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57231310/