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