Асинхронная проблема базы данных Firebase в реальном времени - PullRequest
0 голосов
/ 08 апреля 2020

Введение и цели

Я пытаюсь работать с системой баз данных реального времени, предоставляемой Firebase.

Цель

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

Проблема

У меня проблемы с передачей списка, который загружается с данными String, используя их "Event / Calls" для системы базы данных реального времени. При отладке он показывает, что в нем есть нужные мне строки, но он пуст, когда я передаю его в конструктор.

Что я понимаю

БД работает асинхронно, как упомянуто в это решение. Это означает, что когда данные загружаются в список, это может произойти после того, как они были отправлены в другое действие, а затем ничего не отображаются. Я точно знаю, что мой RecyclerView работает так, как задумано. Посмотрите this на простом примере

В код

Эта часть является операцией с RecyclerView, она вызывается при нажатии кнопки и все, что он делает, это получает строки из БД реального времени, загружает их в список и передает его в адаптер, который создает RecyclerView с TextViews со строками из списка.

public class ListActivity extends AppCompatActivity {

    //Recyclerview variables
    private RecyclerView recyclerView;
    private RecyclerViewAdapter recyclerViewAdapter;
    private RecyclerView.LayoutManager layoutManager;

    //list of String to display (data must be given (Intent?))
    private List<String> questionList = new ArrayList<>();

    private FirebaseDatabase mFirebaseDatabase;
    //This will only reference the message part of the DB
    private DatabaseReference mQuestionsDBReference;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_screen);

        initializeMessageDB();
        listAllQuestions();
        recyclerView = (RecyclerView) findViewById(R.id.recyclerViewID);
        recyclerView.setHasFixedSize(true);

        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);


        System.out.println("[DEBUG-LIST] \n" +
                "Data passed size: " + questionList.size());
        recyclerViewAdapter = new RecyclerViewAdapter(questionList);

        recyclerView.setAdapter(recyclerViewAdapter);
    }

    private void initializeMessageDB() {
        //Access point
        mFirebaseDatabase = FirebaseDatabase.getInstance(); //Instanciate the object
        mQuestionsDBReference = mFirebaseDatabase.getReference().child("messages"); //Only reference the "messages" part
        //System.out.println("[DEBUG] " + mMessagesDatabaseReference.getDatabase());
    }


    public void listAllQuestions() {
        mQuestionsDBReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.getChildrenCount() > 0){
                    for (DataSnapshot snap : dataSnapshot.getChildren()){
                        System.out.println("[DEBUG-LIST] String output: " + snap.child("question").getValue().toString());
                        questionList.add(snap.child("question").getValue().toString());
                    }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        }
        );
    }
}

код адаптера ¡, он получает List от своего конструктора, и все, что он делает, это создает TextView со строкой в ​​нем.

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {


    private List<String> list;


    public RecyclerViewAdapter(List<String> list) {
        this.list = list;
        System.out.println("This list size: " + this.list.size() + " arg list size: " + list.size());
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_view, parent, false);

        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        System.out.println("DEBUG - Recycler: Writting to textView: " + list.get(position));
        holder.textView.setText(list.get(position));
    }

    @Override
    public int getItemCount() { return list.size();}

    public class MyViewHolder extends RecyclerView.ViewHolder {

        TextView textView;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textViewID);
        }
    }
}

Прежде чем вы начнете копаться в коде, если вы считаете, что с помощью другой опции, Cloud Firestore, лучший способ решить эту проблему, дайте мне знать.

TL; DR;

  • Я получаю данные из базы данных реального времени из Firebase.
  • Загрузка List<String> с данными из БД
  • Передать их в качестве аргумента конструктору
  • Данные показывают пустые

Возможные решения, которые я пробовал:

  • I использовали намерения для обмена данными между видами деятельности но привели к тому же.

Примечания:

  • Я тестирую Firebase для разработки приложений
  • Новичок и программист для andriod
  • Android Studio
  • API 29
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...