Как мне извлечь данные из firebase в android studio в точном месте кода?

#java #android #firebase #firebase-realtime-database

#java #Android #firebase #firebase-realtime-database

Вопрос:

Есть ли какой-либо способ извлечь данные из firebase, где находится код? В настоящее время у меня есть ValueEventListeners, но все они выполняются после кода под ними, что делает следующий код недействительным. Я хочу иметь возможность извлекать значение именно там, где находится код, а не позже.

На данный момент я ничего не нашел в Интернете об этом.

Хороший пример моих проблем в коде:

 public void onItemClick(AdapterView<?> l, View v, final int position, long id) {

        FirebaseAuth mAuth = FirebaseAuth.getInstance();
        FirebaseUser user = mAuth.getCurrentUser();
        final String uid = user.getUid();

        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                cCESnapshot = dataSnapshot.child(uid).child("currChallenges").child(challengeList.get(position));
            }

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

            }
        });

        Intent intent = new Intent();
        intent.setClass(this, ChallengeView.class);
        intent.putExtra("snapshot", cCESnapshot.toString());
        intent.putExtra("name", challengeList.get(position));
        startActivity(intent);
    }
  

Значение cCESnapshot равно нулю, потому что intent выполняется перед ValueEventListener .

Комментарии:

1. Вы должны включить создание намерения и startActivity onDataChange . Вы не можете запускать сетевые запросы в основном потоке / синхронизированном.

2. Намерение работает нормально прямо сейчас, если только при передаче его в другой поток вызов Android не будет выполняться первым.

Ответ №1:

Это onDataChange() асинхронный, поэтому единственный способ использовать полученные данные — внутри onDataChange() , пример:

 databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            cCESnapshot = dataSnapshot.child(uid).child("currChallenges").child(challengeList.get(position));

    Intent intent = new Intent();
    intent.setClass(this, ChallengeView.class);
    intent.putExtra("snapshot", cCESnapshot.toString());
    intent.putExtra("name", challengeList.get(position));
    startActivity(intent);
        }

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

        }
    });
  

Ответ №2:

Это асинхронная операция, когда данные поступят, onDataChange будет запущен обратный вызов. Ваш startActivty код будет выполняться последовательно, и именно поэтому вы не получите никакого значения cCESnapshot .

Переместите startActivity код внутри прослушивателя.

Но будьте осторожны, потому что каждый раз onItemClick , когда будет вызываться прослушиватель щелчков, вы будете добавлять прослушиватель событий значений. Таким образом, у вас будет несколько вызовов onDataChange при каждом нажатии и так startActivities далее.

Вместо этого я рекомендую использовать addListenerForSingleValueEvent which будет срабатывать только после однократного изменения данных.