Вставьте данные в firebase - Android - и проверьте указанные c свойства - PullRequest
0 голосов
/ 09 июля 2020

Мне нужно вставить объект урока в firebase, поэтому я помещаю здесь раздел кода onData change. Сначала я получаю снимок данных и вставляю уроки, которые у меня есть в firebase, после этого я просматриваю Список уроков и проверяю: существуют ли дата и время в firebase в any Lesson так что я делаю что-то еще, я вставляю объект урока в firebase. Основная проблема заключается в следующем: когда я вставляю детали урока и нажимаю "добавить", урок попадает в firebase минимум дважды, и если я попробую еще одну вставку, программа войдет в бесконечное l oop. будем рады любой помощи!

   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 Ответ

1 голос
/ 09 июля 2020

При звонке you're adding a listener to the data at. Этот слушатель немедленно прочитает данные и вызовет ваш onDataChange, а затем продолжит прослушивать обновления данных.

Для каждого обновления данных он снова вызывает ваш onDataChange. И поскольку вы обновляете данные внутри onDataChange, это заканчивается бесконечным l oop из setValue -> onDataChange -> setValue -> onDataChange -> ...

Чтобы исправить это, вы обычно вместо этого используете addListenerForSingleValueEvent, так как он получает значение только один раз и не продолжает прослушивать изменения.

Примерно так:

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
})

Обратите внимание: поскольку вы обновляете данные на основе их текущего значения, есть вероятность, что другой пользователь может выполнять ту же операцию почти в то же время. Если это может привести к конфликту обновлений в вашем варианте использования, рассмотрите возможность использования транзакции , которая объединяет чтение и запись из вашего кода в одну (повторяемую) операцию.

...