将数据插入Firebase -Android-并检查特定属性 [英] Insert data to firebase -Android - and check specific properties

查看:55
本文介绍了将数据插入Firebase -Android-并检查特定属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将课程对象插入到Firebase中,因此我将代码的onData更改部分放在此处. 首先,我获得了数据快照并插入了我在firebase中获得的课程,之后,我扫描了课程列表并检查: 如果日期和时间存在任何课程的Firebase中,则我要执行其他操作,将课程对象插入firebase中. 主要问题是: 当我插入课程的详细信息并按添加时,该课程至少要两次输入Firebase,如果尝试再次插入,则程序将进入无限循环. 会很高兴为您提供帮助!

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


推荐答案

调用you're adding a listener to the data at时.该侦听器将立即读取数据并调用您的onDataChange,然后继续侦听数据更新.

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.

对于数据的每次更新,它都会再次调用您的onDataChange.并且由于您正在更新onDataChange中的数据,因此以setValue-> onDataChange-> setValue-> onDataChange->> ...

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->...

要解决此问题,通常应使用addListenerForSingleValueEvent,因为它只会获取一次值,并且不会继续监听更改.

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

所以像这样:

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.

这篇关于将数据插入Firebase -Android-并检查特定属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆