我试图检查数据库中保存的值是否与用户选择匹配,如果确实如此,则更新它,否则不做任何事情。
我已尝试过以下操作,但获得例外:
引起:com.google.firebase.firestore.FirebaseFirestoreException:还必须写入事务中读取的每个文档。
这是我的代码:
//update toolbar titles if they match
final DocumentReference adminDocRef = mDbase.collection("admins").document(adminID);
mDbase.runTransaction(new Transaction.Function<Void>() {
@Override
public Void apply(@NonNull Transaction transaction) throws FirebaseFirestoreException {
DocumentSnapshot adminSnapshot = transaction.get(adminDocRef);
String toolbarTitle = adminSnapshot.getString("displayedUser");
if (userName.equals(toolbarTitle)) {
transaction.update(adminDocRef, "displayedUser", userName);
}
// 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);
}
});
交易是否有条件?如果不是,你会如何解决这个问题?似乎很傻,必须单独获取然后在其中嵌套更新。
非常感谢任何帮助。
谢谢!
答案 0 :(得分:0)
来自answer
的Alex来自documentation交易可能因以下原因而失败:
$.ajax({
type: "POST",
url:"php/page.php",
dataType:"json",
success: function(data)
{
console.log(data);
},
error:function (data) {
console.log("Error"+data)}
});
在你的情况下,我会尝试
$array = new Array();
$ c = 0;
while(condition){
$array[$c] = your_c_object
$c++;
}
echo json_encode($array);
看看是否有效!
答案 1 :(得分:0)
因此,为了有条件地更新我的toolbarTitle,我必须以这种方式级联我的Firestore操作:
DocumentReference adminDocRef = mDbase.collection("admins").document(adminID);
adminDocRef.get().addOnCompleteListener(activity, new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
//assign document value to toolbarTitle
toolbarTitle = document.getString("displayedUser");
if (userName.equals(toolbarTitle)) {
DocumentReference adminDocRef = mDbase.collection("admins").document(adminID);
adminDocRef
.update("displayedUser", toolbarTitle)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "Displayed child has been updated");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "Error: updating displayed child", e);
}
});
Log.d(TAG, "DocumentSnapshot data: " + document.getData());
}
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
有点令人失望的是,我必须这样做,因为看起来它包含在交易中会更有意义。我希望他们允许在交易中使用条件行为。
答案 2 :(得分:0)
实际上,google有一个名为Tasks的类,您可以在其中使用它来同步Firestore调用。
因此,按照您的示例,您可以将其修复为以下内容:
try {
DocumentSnapshot adminDocument = Tasks.await(adminDocRef.get());
if (adminDocument.exists()) {
String toolbarTitle = adminDocument.getString("displayedUser");
if (userName.equals(toolbarTitle)) {
Tasks.await(adminDocRef.update("displayedUser", userName));
//Success
}
}
} catch (ExecutionException e) {
//Error
e.printStackTrace();
} catch (InterruptedException e) {
//Error
e.printStackTrace();
}
这样,您就不需要侦听器了,同时这是有条件的更新。我知道这很晚了,但希望能对某人有所帮助。
[更新]:
请注意,不应在主线程上调用Tasks.await(...)
调用,一种解决方案是使用AsyncTask
。