我有一项活动,我允许用户更改他的UserPIN(Attendance_Records表下的直接键),我已经读过除了删除和添加更新数据之外没有办法更新Firebase实时数据库。我的问题是我必须更新表中的键,但它有多个子键和大量数据。如何访问子键并存储它们?不希望数据更新需要花费很多时间吗?
假设我必须更新密钥:123452
出勤_记录表
除了我在下面尝试过的内容之外,如果还有其他方法,我会全力以赴
修改
我已经达到了能够通过使用以下方式从Attendance_Records表中检索数据的级别:
rootRefAttTable = FirebaseDatabase.getInstance()
.getReference("Attendance_Records")
.child(carriedmPIN);
newRefAttTable = FirebaseDatabase.getInstance()
.getReference("Attendance_Records");
attRec = new Attendance_Records();
然后
private void changeAttTable(){
Log.d("abcd","changeAttTable() reached");
rootRefAttTable.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot yearsnap:dataSnapshot.getChildren()){
yearKey = yearsnap.getKey();
Log.d("abcd","yearKey is: "+yearKey);
monthkeyRef = rootRefAttTable.child(yearKey);
monthkeyRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot monthsnap:dataSnapshot.getChildren()){
monthKey = monthsnap.getKey();
datekeyRef = monthkeyRef.child(monthKey);
datekeyRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot datesnap:dataSnapshot.getChildren()){
dateKey = datesnap.getKey();
date = datesnap.child("date").getValue(String.class);
enteryDate = datesnap.child("entryDate").getValue(String.class);
inTime = datesnap.child("inTime").getValue(String.class);
month = datesnap.child("month").getValue(String.class);
myID = datesnap.child("myID").getValue(String.class);
outTime = datesnap.child("outTime").getValue(String.class);
status = datesnap.child("status").getValue(String.class);
year = datesnap.child("year").getValue(String.class);
addDataAttTable();
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void getValuesAtt(){
Log.d("abcd","getValuesAtt() reached");
attRec.setYear(year);
attRec.setMonth(month);
attRec.setMyID(myID);
attRec.setEntryDate(enteryDate);
attRec.setStatus(status);
attRec.setOutTime(outTime);
attRec.setInTime(inTime);
attRec.setDate(date);
}
private void addDataAttTable(){
Log.d("abcd","addDataAttTable() reached");
getValuesAtt();
newRefAttTable.child(carriedmPIN).removeValue();
newRefAttTable.child(enterednewmpin).child(yearKey).child(monthKey).child(dateKey).setValue(attRec);
}
但是,添加到数据库的方式不应该如此:
之前
后
对于更新前的图片感到抱歉。更新后(123450到123459),第3个月和第4个月连在一起,现在我没有2年(2018年和2019年假设),否则我认为他们也会加入。我怎么能纠正这个?
答案 0 :(得分:2)
我终于做到了!!
有时候你会考虑更深层次的逻辑,但只需要一个简单的代码就可以了!
我是这样做的:
rootRefAttTable = FirebaseDatabase.getInstance().getReference("Attendance_Records").child(carriedmPIN);
newRefAttTable = FirebaseDatabase.getInstance().getReference("Attendance_Records");
carrymPIN是PIN用户需要更改的内容。
private void changeAttTable() {
Log.d("abcd","changeAttTable() reached");
rootRefAttTable.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot yearsnap:dataSnapshot.getChildren()){
for(DataSnapshot monthsnap:yearsnap.getChildren()){
for(DataSnapshot datesnap:monthsnap.getChildren()){
dateAtt = datesnap.child("date").getValue(String.class);
Log.d("abcd","date is: "+dateAtt);
entrydateAtt = datesnap.child("entryDate").getValue(String.class);
Log.d("abcd","enteryDate is: "+entrydateAtt);
intimeAtt = datesnap.child("inTime").getValue(String.class);
Log.d("abcd","inTime is: "+intimeAtt);
monthAtt = datesnap.child("month").getValue(String.class);
Log.d("abcd","month is: "+monthAtt);
myidAtt = datesnap.child("myID").getValue(String.class);
Log.d("abcd","myID is: "+myidAtt);
outtimeAtt = datesnap.child("outTime").getValue(String.class);
Log.d("abcd","outTime is: "+outtimeAtt);
statusAtt = datesnap.child("status").getValue(String.class);
Log.d("abcd","status is: "+statusAtt);
yearAtt = datesnap.child("year").getValue(String.class);
Log.d("abcd","year is: "+yearAtt);
getValuesAtt();
newRefAttTable.child(enterednewmpin).child(yearsnap.getKey()).child(monthsnap.getKey()).child(datesnap.getKey()).setValue(attRec);
}
}
}
newRefAttTable.child(carriedmPIN).removeValue();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void getValuesAtt(){
Log.d("abcd","getValuesAtt() reached");
attRec.setYear(yearAtt);
attRec.setMonth(monthAtt);
attRec.setMyID(myidAtt);
attRec.setEntryDate(entrydateAtt);
attRec.setStatus(statusAtt);
attRec.setOutTime(outtimeAtt);
attRec.setInTime(intimeAtt);
attRec.setDate(dateAtt);
}
我很开心!!很长一段时间我一直坚持这个! :P
答案 1 :(得分:1)
我想这里的问题是monthKey
是常见的 04 ,如果我做对了,所以默认情况下Firebase会将它视为同一个孩子,并将添加所有内容。
但回到主要问题,更改引脚,你试过这个:
修改强> 为什么不通过使用Firebase为添加的每个孩子提供的唯一ID来更改数据库的结构,并将其用作密钥,然后在您的孩子中为该针添加一个字段?
首先,如果您的用户拥有常见的PIN,那么首先要确保您的所有孩子都不会发生冲突,其次,它会让您更轻松地检索临时对象上的整个用户对象,更改其中包含PIN值,然后使用提供的唯一ID将其再次推送给同一个孩子!
如果您想知道如何获取此唯一ID,我还建议将其保存为对象中的字段,在推送对象时保存它,并在需要时从检索到的临时对象中检索。
处理所有这些问题的最佳方法是通过onChildAdded
和onChildChanged
方法而不是手动(提示:尝试将数据库拆分为不同的引用,让您更轻松地管理ChildListener
)