Home > Mobile >  How to constantly update query for Firebase Realtime Database with LiveData and ViewModel in Android
How to constantly update query for Firebase Realtime Database with LiveData and ViewModel in Android

Time:06-26

I use Firebase Realtime Database and LiveData with ViewModel in Android and I would like to constantly update the query.

Here is the ViewModel class:

public class ViewModel_MainActivity extends ViewModel {


    /*
    LiveData with Database query for the Firebase node "Ratings"
    */

    private static long currentTimeMillisRating = System.currentTimeMillis();
    private static double pastMinuteForDisplayingRatings = 1;
    private static long pastTimeMillisRatings = System.currentTimeMillis() - (long) (pastMinuteForDisplayingRatings * 60 * 60 * 1000);


    private static final Query QUERY_RATINGS =
            FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference().child(DB_SQLite_Firebase_Entries.FIREBASE_NODE_RATINGS).orderByChild(DB_SQLite_Firebase_Entries.FIREBASE_RATINGDATEINMILLISECONDS).endAt(pastTimeMillisRatings);


    private final LiveData_FirebaseRating liveData_firebaseRating = new LiveData_FirebaseRating(QUERY_RATINGS);

    @NonNull
    public LiveData_FirebaseRating getDataSnapshotLiveData_FirebaseRating() {
        Log.e("LogTag_ViMo", "pastTimeMillisRatings: "   pastTimeMillisRatings);
        return liveData_firebaseRating;
    }


}

Here is the LiveData class:

public class LiveData_FirebaseRating extends LiveData<DataSnapshot> {
    private static final String LOG_TAG = "LiveData_FirebaseRating";

    private Query query;
    private final LiveData_FirebaseRating.MyValueEventListener listener = new LiveData_FirebaseRating.MyValueEventListener();

    DataSnapshot currentDataSnapShotFromFirebase;

    public LiveData_FirebaseRating(Query query) {
        this.query = query;
    }

    public LiveData_FirebaseRating(DatabaseReference ref) {
        this.query = ref;
    }

    public void changeQuery(Query newQuery) {
        this.query = newQuery;
    }

    public DataSnapshot getCurrentDataSnapShotFromFirebase() {
        return currentDataSnapShotFromFirebase;
    }

    public void setCurrentDataSnapShotFromFirebase(DataSnapshot currentDataSnapShotFromFirebase) {
        this.currentDataSnapShotFromFirebase = currentDataSnapShotFromFirebase;
    }

    @Override
    protected void onActive() {
        Log.d(LOG_TAG, "onActive");
        query.addValueEventListener(listener);
    }

    @Override
    protected void onInactive() {
        Log.d(LOG_TAG, "onInactive");
        query.removeEventListener(listener);
    }

    private class MyValueEventListener implements ValueEventListener {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {


            setValue(dataSnapshot);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(LOG_TAG, "Can't listen to query "   query, databaseError.toException());
        }
    }
}

And here is the part of the main activity, where the live data and view model are created and observed:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        binding = ActivityMainBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);
       
        /*
        Initiate View Model with LiveData for Firebase
         */



        rootRef_Firebase = FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference();
        viewModel = new ViewModelProvider(this).get(ViewModel_MainActivity.class);

        liveData_firebaseRating = viewModel.getDataSnapshotLiveData_FirebaseRating();
        liveData_firebaseRating.observe(this, new Observer<DataSnapshot>() {

            @Override
            public void onChanged(@Nullable DataSnapshot dataSnapshot) {
                liveData_firebaseRating.setCurrentDataSnapShotFromFirebase(dataSnapshot);
                if(liveData_firebaseRating.getCurrentDataSnapShotFromFirebase()!=null) {
                    //Do something with the dataSnapshot of the query
                }
            }// end onChange
        }); //end observe



    }

So my problem lies in the non-updating of the QUERY_RATINGS in the class ViewModel_MainActivity . What I want is to return all the nodes from the FIREBASE_NODE_RATINGS whose at attribute FIREBASE_RATINGDATEINMILLISECONDS is older than 1 Minute (meaning that the entry was created at least 1 Minute before the current time slot). How can I do that such that I always get these nodes?

CodePudding user response:

Firebase Query objects are immutable, and their parameters are fixed values. So there is no way to update the existing query, nor is there a "one minute ago" value that automatically updates.

The options I can quickly think off:

  • Create a new query frequently to capture the new full range of relevant nodes.
  • Create a new query frequently to capture only the new nodes (by combining startAt and endAt) and merge them with the results you already have.
  • Remove the condition from the query, and perform the filtering in your application code.

Based on what I know, I'd probably start with the third option as it seems the simplest.

  • Related