使用多个子键重命名firebase中的键

时间:2018-05-03 10:31:48

标签: java android firebase firebase-realtime-database

我有一项活动,我允许用户更改他的UserPIN(Attendance_Records表下的直接键),我已经读过除了删除和添加更新数据之外没有办法更新Firebase实时数据库。我的问题是我必须更新表中的键,但它有多个子键和大量数据。如何访问子键并存储它们?不希望数据更新需要花费很多时间吗?

假设我必须更新密钥:123452

出勤_记录表

enter image description here

除了我在下面尝试过的内容之外,如果还有其他方法,我会全力以赴

修改

我已经达到了能够通过使用以下方式从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);
}

但是,添加到数据库的方式不应该如此:

之前

enter image description here

enter image description here

对于更新前的图片感到抱歉。更新后(123450到123459),第3个月和第4个月连在一起,现在我没有2年(2018年和2019年假设),否则我认为他们也会加入。我怎么能纠正这个?

2 个答案:

答案 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,我还建议将其保存为对象中的字段,在推送对象时保存它,并在需要时从检索到的临时对象中检索。

处理所有这些问题的最佳方法是通过onChildAddedonChildChanged方法而不是手动提示:尝试将数据库拆分为不同的引用,让您更轻松地管理ChildListener