Назначения, сделанные внутри ValueEventListeners базы данных Firebase, не отражаются - PullRequest
1 голос
/ 22 июня 2019

У меня есть некоторые глобальные переменные, значения которых необходимо динамически обновлять в соответствии с базой данных.Поэтому я попытался использовать ValueEventListener(). Я могу успешно прочитать предполагаемое значение и показать это в журнале.

Но, к сожалению, когда я пытаюсь сохранить это значение в ранее объявленной некоторой глобальной переменной, оно не работает, хотяДоза не показывает какую-либо ошибку, но она не может сохранить намеченное значение (я даю код, где вы можете найти сообщение журнала, чтобы показать размер списка после обновления через ValueEventListener(), и его вывод все еще показывает 0 ..

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";


    private String RxuserId;
    private String currentuserName;
    private String currentuser,path;

    public ArrayList<String> mToken;

    private FirebaseDatabase database;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //for keeping the keyboard hidden
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        Intent intent=getIntent();
        RxuserId=intent.getStringExtra("Id");
        Rxusrnm=intent.getStringExtra("Name");
        //storeName(usrnm);
        currentuserName=SharedPrefManager.getmInstnce(this).getUsername();
        currentuser=SharedPrefManager.getmInstnce(this).getUserID();


        database = FirebaseDatabase.getInstance();



        providers = new ArrayList<>();
        mToken = new ArrayList<>();


        if(RxuserId!=null){
            database.getReference().child("users").child(RxuserId).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    mToken.add(dataSnapshot.child("fcm token").getValue().toString());
                    mToken.add("nsks");
                    Toast.makeText(getApplicationContext(),"REQUIRED TOKRN  "+dataSnapshot.child("fcm token").getValue().toString(),Toast.LENGTH_LONG).show();
                    Log.d(TAG,"REQUIRED TOKRN  "+dataSnapshot.child("fcm token").getValue().toString());
                 //These two are shown correctly
                }

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

                }
            });

        }

        Log.d(TAG,"REQUIRED TOKRN  "+mToken.size())//which shows 0 ;
}

где я делаю неправильно? И что мне делать, чтобы я мог обновить значение глобальной переменной изнутри ValueEventListener()?

Спасибо

1 Ответ

0 голосов
/ 23 июня 2019

Firebase's ValueEventListener работает асинхронно .Вот почему ваш код регистрации в конце печатается раньше, чем ваш асинхронный слушатель срабатывает.Данные из firebase действительно добавляются (отражаются) в глобальную переменную, но после журнала.

Если вы хотите выполнить некоторую логику при изменении данных в firebase, вы должны выполнять свою логику непосредственно внутри ValueEventListener или использовать LiveData или RxJava .

Вот как использовать LiveData:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    private String RxuserId;
    public ArrayList<String> mToken;
    MutableLiveData<String> data = new MutableLiveData<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RxuserId = intent.getStringExtra("Id");

        mToken = new ArrayList<>();

        if(RxuserId != null){            
            database.getReference().child("users").child(RxuserId).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    data.setValue(dataSnapshot.child("fcm token").getValue().toString());
                }

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

                }
            });   
        }

        data.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                mToken.add(s);
                Toast.makeText(getApplicationContext(), "REQUIRED TOKRN  " + s,Toast.LENGTH_LONG).show();

                Log.d(TAG,"REQUIRED TOKRN  " + string);
                Log.d(TAG,"REQUIRED TOKRN  " + mToken.size())
            }
        });
    }
}

Это не очень полезный случай для LivaData.Обычно LiveData используется, когда логика с firebse находится в другом классе (в репозитории MVVM) для изменения пользовательского интерфейса в соответствии с изменением данных.

Список пользователей может храниться так:

// User  is model class
List<User> users = new ArrayList<>();

final MutableLiveData<List<User>> data = new MutableLiveData<>();

database.child("users").addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<User> users = new ArrayList<>();

        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            User user = ds.getValue(User.class);
            users.add(user);
        }

        data.setValue(users); // data can be observed later
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...