Let's say I have this object in db
{
value:60
status:PLAYING // could be PLAYING or FINISHED for simplicity
}
and I want to listen this object, or want to be notified when status becomes FINISHED
Currently following is not working
myRef.child("status").equalTo("PLAYING").addValueEventLisener...
it just triggers onDataChange regardless of status and returns snapshot value as null
On the other hand, if I omit PLAYING and use as following:
myRef.child("status").addValueEventLisener...
onDataChange is triggered as usual and snapshot value is not null
I have tried orderByChild it is not helping or I am doing things wrong.
That is an orderByValue() query:
myRef.child("status").orderByValue().equalTo("PLAYING")
Related
again :) I got a question about Cloud Firestore and Kotlin.
I need to get data from firestore with some code like this:
{
val comments = mutableListOf<Comment>()
val firestore = FirebaseFirestore.getInstance()
firestore.collection(collection).document(documentID).collection("comments")
.addSnapshotListener { querySnapshot, firebaseFirestoreException ->
comments = querySnapshot?.toObjects(Comment::class.java)!!
// do something with 'comments'. Works: comments is populated
}
// do something with variable 'comments'. Doesn't work: comments is now empty
}
The variable 'comments' gets populated inside the listener curly brackets but when the listener ends, the value goes back to 0.
I've researched online and found examples in JAVA that works perfectly this way, for example:
https://youtu.be/691K6NPp2Y8?t=246
My purpose is to fetch data only ONCE from the Cloud Firestore and store that value in a global variable, comments.
Please, let me know if you have a solution for this.
Thank you.
The value doesn't "go back to zero". You should understand that the database query is asynchronous, and addSnapshotListener returns immediately, before the query completes. The final value is only known when the listener is invoked some time later.
Also, you should know that if you just want to query a single time, you should use get() instead of addSnapshotListener(). It is also asynchronous and returns immediately, and the Task it returns will get invoked some time later. There are no synchronous options that block the caller until the query is complete - you will need to learn how to do your work asynchronously.
Problem:
I am using Room Persistence Library and so far everything is working fine except that there is a data from select query which I need synchronously as I am calling it from a Periodic Job (Work Manager's Worker). I have defined the return type to be LiveData as I am also accessing it for display purposes in UI and so observers are great for that but now I also need the same data in Job.
Code Snippet
#Query("SELECT * from readings ORDER BY date, time ASC")
LiveData<List<Reading>> getAllReadings();
Tried
I have tried the getValue() method in LiveData but it returns null as the data is not loaded in LiveData while making the query.
readingDao().getAllReadings().getValue() // returns null
Possible Solution
There is only one solution that I can think of which is to duplicate the getAllReadings query with a different name and return type (without LiveData) but I don't think this is a clean approach as it increases duplication of code just to get a synchronous return type.
Please let me know if there is any other solution or perhaps some way to synchronously access data from LiveData variable.
You can allow main thread query when you initialize Room DB, but it's clearly not desirable. This will give you the synchronous behavior but will block user interface. Is there a specific reason you want this to be synchronous?
The reason why getValue() is returning null is because Room is querying data asynchronously. You can attach an observer or a callback function to get result when the query is finished. You can display the result to the UI or chain another call for sequential operation etc from there.
I use RxJava to wrap my query request for asynchronous query but I you can also use AsyncTask.
I want to get the data stored in the DB without being restricted to access it only when there is a data change.
I've seen this post from 2016:
How to access Firebase data without using addValueEventListener
Which suggested to use addValueEventListener.
I've also seen this post:
Accessing data in Firebase databse
Without good answer.
ValueEventListener will trigger the onDataChange only when the database will have a change.
How else can I access the database without something being changed in the database?
For now I will write simple harmless change in order to access the data, but i'm wondering if it's the only way to do it.
Thanks
Of course this is absolutely not true. You can retrieve data whenever you like to.
Firstly I would like to advice you to read this documentation reference.
Secondly I provide you with what you really asked for.
If you read the documentation you will notice that it states the following:
The onDataChange() method in this class is triggered once when the listener is attached and again every time the data changes, including the children.
That means that with this code:
databaseReference.removeEventListener(eventListener);
With that method you would be able to detatch any listener so it only listens once or detatch it whenever you want to.
There is a method for only retrieving data once though.
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "Data retrieved.");
}
...
}
This method will exactly call onDataChange once or respectively onCancelled.
In my application I'm inserting user like below
realm.beginTransaction();
realm.copyToRealmOrUpdate(user);
realm.commitTransaction();
I want to display and message if data inserted correctly. How to check if data insertion works successfully or not.
I know if I use realm.executeTransactionAsync() method I can get callback for onSuccess() and onError(). But It does not make any sense to insert one object asynchronously just to get access in to onSuccess().
The line realm.copyToRealmOrUpdate(user); will return an object of type user which is managed by realm signifying that it got inserted. If that object is null that would imply that the transaction did not succeed in which case it would have crashed with an exception.
Is it possible to check if child data exists over a Firebase DataReference when using observeChildEvent? I'm using onChildEventListener to fill a RecyclerView on my application but during the data change, I show a ProgressBar. The problem appears when there's no data in the current query, so I never receive an event and I can't hide my progressBar.
Is there any way to achieve this without launch a previous observeSingleValueEvent with a limit(1) value to check in the dataSnapshot if there is available data?
I'm using RxFirebase2 to work with Firebase, so I did a method to check if a DatabaseReference have childrens, using it together with RxJava to avoid use OnChildEvents when my reference have no childrens:
public Single<Boolean> checkIfRefHaveAvailableChild(DatabaseReference databaseReference){
final Query query = databaseReference.limitToFirst(MIN_RETRIEVE_DATA);
return RxFirebaseDatabase.observeSingleValueEvent(query)
.subscribeOn(Schedulers.io())
.take(1)
.map(dataSnapshot -> dataSnapshot.hasChildren())
.single(false);
}