How to know in firestore when a collection have changes? - java

I have a collection who contains items of a restaurant menu, i want to know when a new item is added or have a change(price, name, description), because i want to notify this to the app and download this changes in a internal database.
I was trying to create a firebase function to modify a field called version and this way campare version in the app vs firebase version of the collection but i really dont know how to work with firebase functions.
can someone give a recomendation?

Cloud Firestore is a flexible, scalable database which keeps your data in sync across client apps through realtime listeners and offers offline support for mobile and web applications.
So in order to know if something has been changed in your database, you need to attach a listner on a particular location. Assuming you have a collection named cities and a document named SF, plase use the following code. It's a straight forward example.
DocumentReference docRef = db.collection("cities").document("SF");
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot snapshot, #Nullable FirebaseFirestoreException e) {
// see which fields changed
}
});
Unlike Firebase Realtime database, Cloud Firestore has data persistence enabled by default. So there is no need to keep your data also in a internal database.

Related

Is there is way to update the data to user once changed without opening the app?

Recently, I'm working on an app which is used to set alarm to other users who are logged in to the app, But problem is how can I set alarm to other user when the data is changed in the real-time database of firebase. Is there is any way that if I update the data of other user and It should to retrieved and updated in other users application and alarm should set when data is received.
DatabaseReference duser = FirebaseDatabase.getInstance().getReference("Alarm");
duser.keepSynced(true);
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
duser.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String ids = snapshot.child(id).getKey();
Log.d("ID : ", ids+"");
String hour = snapshot.child(id).child("hour").toString();
Log.d("HOUR : ", hour+"");
String minute = snapshot.child(id).child("minute").toString();
}
Database
This is my database.
If yes please explain me, how to do.
What does Query#addListenerForSingleValueEvent(ValueEventListener listener) method it:
Add a listener for a single change in the data at this location.
This means that you'll get the data only once, without future updates. If you want a persistent listener to listen for real-time changes, then you use Query#addValueEventListener(ValueEventListener listener) that:
Add a listener for changes in the data at this location.
So each time something is added, changed, or deleted you're notified almost instantly. If you want, you can also use a library for that, which is called Firebase-UI.

Can't write on Realtime Database [duplicate]

I have created a Firebase, and I can write data into Authentication.
But, I could not write data into realtime database.
I have connected to Firebase
I have add Realtime Database
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:28.4.1')
// Declare the dependency for the Realtime Database library
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-database:20.0.2'
I have set rules of read and write to ture
{
"rules": {
".read": true,
".write": true
}
}
I tried this to write data into Firebase but I get noting
// Write a message to the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
myRef.setValue("Hello, World!");
// Write a message to the database
FirebaseDatabase.getInstance().getReference().child("aaa").child("bbb").setValue("ccc");
FirebaseDatabase.getInstance().getReference().child("aaa").child("bbb").setValue("ccc");
The code for writing looks fine, so I think the problem may be elsewhere.
If you created the Firebase console after you downloaded the google-services.json file, that file will not contain the correct URL, and the SDK may not be able to find your database on the server.
To solve that problem, you can either:
Download an updated google-services.json and use that in your app, or
Provide the database URL in your code with FirebaseDatabase database = FirebaseDatabase.getInstance("database URL here");
My code works this morning, but I did nothing except go to bed. As shown in the picture, the second step has changed. I clicked that Add the Realtime Database SDK to your app button thousands of times, and it was still a button. Surprisingly, it has changed to a checked state.
I did the google-services.json part as #FrankvanPuffelen said yesterday, but it didn't work.
I have restarted the Android Studio a lot of times and didn't work.
Maybe I should try close the computer lid next time.
But now I know that one should have the second step checked rather than keep it as a unchecked button.

Reading Images from multiple nodes in Firebase

So I'm making a wallpaper app that has various categories but I want to display all images from all nodes in Firebase in one fragment called Random, I also want the Images to shuffle images from each parent node
The following is my Firebase structure :
There are also child nodes in them :
The following is my java code from my Random fragment :
private void getWallpapers() {
progressBar.setVisibility(View.VISIBLE);
myRef = database.getReference().child("Wallpaper").child("Random");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
collectionsArray.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
wallpaper z = postSnapshot.getValue(wallpaper.class);
collectionsArray.add(z);
}
Collections.reverse(collectionsArray);
progressBar.setVisibility(View.GONE);
mAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
System.out.println("Error Reading from DB");
}
});
There is no built-in query that can get elements across different nodes in the database. Seeing that you have different structures for each category, the best option I can think of is to duplicate the data. This practice is called denormalization and is a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database.
So you should create another node that will hold all images you have in the database, no matter from which category belongs. To select a random wallpaper, please check my answer from the following post:
How to get unique random product in node Firebase?
Also remember, when you are duplicating data, there is one thing that you need to keep in mind. In the same way, you are adding data, you need to maintain it. In other words, if you want to update/delete a wallpaper, you need to do it in every place that it exists.
If you might also be interested in:
What is denormalization in Firebase Cloud Firestore?

Does Using SnapshotParser while querying firestore an expensive operation?

Does using SnapshotParser while querying Firestore an expensive operation in terms of read operation?
We are building query in our app like this:
options = new FirestoreRecyclerOptions.Builder<Item>()
.setQuery(query, new SnapshotParser<Item>() {
#NonNull
#Override
public Item parseSnapshot(#NonNull DocumentSnapshot snapshot) {
Item item = snapshot.toObject(Item.class);
item.setId(snapshot.getId());
return item;
}
})
.setLifecycleOwner(this)
So while reading data from server, does SnapshotParser will make extra read operation (or hit server again) or it will parse using already read data?
Would it be the same operation(in terms of server hit) with or without SnapshotParser?
Please explain, if anything is missed, please let me know? Sorry for bad english.
From the official documentation of Firebsase-UI library:
If you need to customize how your model class is parsed, you can use a custom SnapshotParser.
So if you need to customize your model class it doesn't mean that you are creating extra read operations. The parseSnapshot() method uses as an argument a DocumentSnapshot object which contains the data set that you are getting from the database for which you are already charged in terms of read operations. This is happening if the the query return data. If your query does not return any data, you are still charged but only with a single read operation.

How to automatically detect new document in collection of Firebase Firestore?

I want to make an Android chat application. So I want to know how to get data from Firebase Firestore automatically, when new document create? Actually I do not wanna use add snapshot listener because of its give real-time data changes of a single document but want to find out real time updated Firebase Firestore document. Please suggest me.
I don't know if you can do this without a snapshot listener.
Check this code, if it is what you want.
private void addRealtimeUpdate() {
DocumentReference contactListener=db.collection("PhoneBook").document("Contacts");
contactListener.addSnapshotListener(new EventListener < DocumentSnapshot > () {
#Override
public void onEvent(DocumentSnapshot documentSnapshot,
FirebaseFirestoreException e) {
if (e != null) {
Log.d("ERROR", e.getMessage());
return;
}
if (documentSnapshot != null && documentSnapshot.exists()) {
Toast.makeText(MainActivity.this, "Current data:" +
documentSnapshot.getData(), Toast.LENGTH_SHORT).show();
}
}
});
}
To solve this, I recommend you to use CollectionReference's get() method. This is the correspondent addListenerForSingleValueEvent() method from Firebase real-time database.
Executes the query and returns the results as a QuerySnapshot.
If you want to use Firebase-UI library, this is a recommended way in which you can retrieve data from a Cloud Firestore database and display it in a RecyclerView using FirestoreRecyclerAdapter.
I don't know if you can do it with firestore but with realtime database you can use the .on(). If the rest of your app is using firestore, each project can use both a cloud firestore and a realtime database. The docs are really simple.

Categories