我正在尝试将数据从实时数据库中的一条路径移动到另一条路径。 因此,我必须将数据从一个路径(1)复制到另一路径(2),然后从(1)中删除数据。
我尝试了以下代码:
ConfiguracaoFirebase.getFirebaseReferenceRelatorios().limitToFirst(20)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (final DataSnapshot ids: dataSnapshot.getChildren()){
String ano = ids.child("ano").getValue().toString();
String mes = ids.child("mes").getValue().toString();
String dia = ids.child("dia").getValue().toString();
String nomePaciente = ids.child("nomePaciente").getValue().toString();
moveFirebaseRecord(ids.getRef(), ConfiguracaoFirebase.getFirebaseReferenceReports().child(nomePaciente).child(ano).child(mes).child(dia).child(ids.getKey()));
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
和此功能moveFirebaseRecord:
public void moveFirebaseRecord(final DatabaseReference fromPath, final DatabaseReference toPath) {
fromPath.addListenerForSingleValueEvent(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
toPath.setValue(dataSnapshot.getValue(), new DatabaseReference.CompletionListener() {
@Override
public void onComplete(@Nullable DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
fromPath.removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Constant.print("REMOVED: " + fromPath.getKey());
}
});
}
});
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
但是,当我运行时,我看到它将fromPath正确地移动到toPath,但是紧接在它之后删除了刚创建的toPath ...因此它正在删除toPath和fromPath ... 有人知道为什么会发生这种情况,以及如何从Firebase剪切和移动数据?预先感谢。
答案 0 :(得分:1)
如果toPath
在最初看起来已经写完之后被删除,通常是由安全规则引起的。因此,请检查用户是否真的有权写入该路径。
通常,我强烈建议将新值的写入和现有值的删除合并到单个多位置更新中,如下所示:
public void onDataChange(DataSnapshot dataSnapshot)
{
Map<String, Object> updates = new HashMap<String, Object>();
updates["/path/to/new/value"] = dataSnapshot.getValue();
updates["/path/to/old/value"] = null;
rootRef.updateChildren(updates).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Constant.print("REMOVED: " + fromPath.getKey());
}
});
});
}
这样,要么两个操作都成功,要么都不执行(例如,如果安全规则拒绝另一个操作)。