Insert data to firebase -Android - and check specific properties

删除回忆录丶 提交于 2020-07-23 06:54:21

问题


I need to insert lesson object to firebase, so I put here the onData change section of code. First of all I get data snapshot and insert the lessons that I have in firebase, after that I scan the List of Lessons and check: if the date and time exist in the firebase in any Lesson so I do something else I insert the lesson object to firebase . The main problem is : when I insert the details of the lesson and press add, the lesson enter to the firebase twice minimum, and if I try another insertion the program enter to infinite loop . will be happy for any help !

   ArrayList<Lesson> existLesson=new ArrayList<>();
    List<String> keys = new ArrayList<>();
    int counter=0;
public void getLessons(DataSnapshot dataSnapshot){

        //insert the lessons to "existLesson" arrayList
        for (DataSnapshot keyNode : dataSnapshot.getChildren()) {
                keys.add(keyNode.getKey());
                Lesson lesson = keyNode.getValue(Lesson.class);
                existLesson.add(lesson);
                Log.i(tag, "data : " + lesson.getSubject());
        }//for
}

    int flag=1;
    @Override
    public void addLesson(final String subject, final String topic, final String date, final String time) {


        mDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    getLessons(dataSnapshot);

                    //Check if date and time is busy
                    for (Lesson lessonToCheck : existLesson) {
                        if (lessonToCheck.getDate().equals(date) && lessonToCheck.getTime().equals(time)) {  
                            flag = 0;
                        } else {
                            flag = 1;
                        }
                    }//for
                    if (flag == 0) {
                        Toast.makeText(LessonDetails.this, "date exist", Toast.LENGTH_SHORT).show();
                        // Check empty lessons
                        nearestLessons(existLesson, date, time);
                    } else {
                        if (flag == 1) {
                            String id = mDatabase.push().getKey();
                            Lesson lesson = new Lesson(subject, topic, date, time, id); //create lesson
                            Toast.makeText(LessonDetails.this,
                                    subject + " - " + topic + " - " + date + " - " + time, Toast.LENGTH_SHORT).show();
                            mDatabase.child(id).setValue(lesson);
                        } //add lesson to DB
                    } //else

         Log.i(tag,"end");
            } //onDataChange



回答1:


When you call you're adding a listener to the data at. This listener will immediately read the data and call your onDataChange, and then continues to listen for updates to the data.

For each update to the data, it calls your onDataChange again. And since you're updating the data inside onDataChange, this ends in an endless loop of setValue->onDataChange->setValue->onDataChange->...

To fix this, you'd typically use addListenerForSingleValueEvent instead, as this only gets the value once and doesn't continue listening for changes.

So something like:

mDatabase.addForListenerValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            getLessons(dataSnapshot);

            //Check if date and time is busy
            for (Lesson lessonToCheck : existLesson) {
                if (lessonToCheck.getDate().equals(date) && lessonToCheck.getTime().equals(time)) {  
                    flag = 0;
                } else {
                    flag = 1;
                }
            }//for
            if (flag == 0) {
                Toast.makeText(LessonDetails.this, "date exist", Toast.LENGTH_SHORT).show();
                // Check empty lessons
                nearestLessons(existLesson, date, time);
            } else {
                if (flag == 1) {
                    String id = mDatabase.push().getKey();
                    Lesson lesson = new Lesson(subject, topic, date, time, id); //create lesson
                    Toast.makeText(LessonDetails.this,
                            subject + " - " + topic + " - " + date + " - " + time, Toast.LENGTH_SHORT).show();
                    mDatabase.child(id).setValue(lesson);
                } //add lesson to DB
            } //else

        Log.i(tag,"end");
    } //onDataChange
})

Note that, since you're updating the data based on its current value, there's a chance that another user may be doing the same operation at almost the same time. If this can lead to conflicting updates in your use-case, consider using a transaction which combines the read and write from your code into a single (repeatable) operation.



来源:https://stackoverflow.com/questions/62803569/insert-data-to-firebase-android-and-check-specific-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!