How to Handle Offline Transactions in Firebase Realtime Database? - android

I have an addValueEventListener which listens to any value changes in Firebase Realtime Database. In online mode, everything is working fine.
But in offline mode, device is offline and my Web Server has done multiple transactions on Firebase Realtime Database on same value for which I put the listener from Android. After the device comes online, it will only listen for the last transaction and skipping the other transactions done in between.
PFB reference link. PFB code which i have done so far:
FirebaseDatabase.getInstance().setPersistenceEnabled(false);
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference myRef = firebaseDatabase.getReference("mykey");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
HashMap<String, Object> key_Value = (HashMap<String, Object>) dataSnapshot.getValue();
for (String key : key_Value.keySet()) {
System.out.println("firebase key is "+key);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("feroz ", "Failed to read value.", error.toException());
}
});
}

The Firebase Realtime Database stores information came back from an inquiry for use when disconnected. For questions developed while disconnected, the Firebase Realtime Database keeps on working for already stacked information. On the off chance that the asked for information hasn't stacked, the Firebase Realtime Database loads information from the nearby reserve. When we return online our information will stack and mirror the inquiry.
For instance, here we have a bit of code in our application that questions for the last four things in our Firebase Realtime Database of scores
DatabaseReference scoresRef = FirebaseDatabase.getInstance().getReference("scores");
scoresRef.orderByValue().limitToLast(4).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String previousChild) {
System.out.println("The " + snapshot.getKey() + " dinosaur's score is " + snapshot.getValue());
}
});

Related

How to delete a certain data in the Firebase Database?

I'm developing a social networking app, where users can follow other users and like their posts, comments ...
Whenever some user follows someone, it shows in a notification fragment in the other user account to inform him that he has a new follower.
The problem is that I couldn't remove the notification when the user hits unfollow. Here is what I have tried:
if ( holder.btn_follow.getText().toString().equals("follow"))
{
addNotifications(user.getId());
}
else{
FirebaseDatabase.getInstance().getReference("Notifications").child(user.getId()).removeValue();
}
and here is how I added notification:
private void addNotifications(String userid)
{
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Notifications").child(userid);
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("userid", firebaseUser.getUid());
hashMap.put("text"," started following you");
hashMap.put("postid","");
hashMap.put("ispost",false);
reference.push().setValue(hashMap);
}
the problem with my code is that whenever the user unfollows someone, all the notifications from that user are deleted including his likes and comments. all I want is to delete "started following you".
Here is how it looks in the Firebase database.
Use Firebase Query refers to Firebase Docs, it will be something like this
Query queryRef = mReference.child("Notifications").child(userId).orderByChild("text").equalTo("start following you");
queryRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String previousChild) {
// snapshot.getRef().setValue(null);
snapshot.getRef().remove();
}
});

Firebase error message if directory doesn't exist

I want to show error message with toast if firebase database doesn't exist.
an example: The app will not be able to connect to the firebase database when when I delete the database, delete the firebase project or if there is no database.
So the app should display an error toast message "databese doesn't exist" or "not connection to databese" when all this happens.
Because you didn't mention in your question if you are looking for Firebase Real-time database or Cloud Firestore, I'll give you an answer for both. So in case of Firebase Real-time Database, there is a special location at /.info/connected which is updated every time the Firebase Real-time Database client's connection state changes. Here is an example from the official documentation:
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
System.out.println("connected");
} else {
System.out.println("not connected");
}
}
#Override
public void onCancelled(DatabaseError error) {
System.err.println("Listener was cancelled");
}
});
This is how you can know if the client is connected to the server or not.
In case of Cloud Firestore, when you are offline and you are using a get() call, the result will be from the cached copy of the Cloud Firestore data that your app is actively using.
To check if the data is from cache or from Firestore servers, you can use the following line of code:
String source = querySnapshot.getMetadata().isFromCache() ? "Local Cache" : "Firebase Server";
Reference your main node of your database and use exists() to check if that reference exists or not
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists())
Log.e("No database","Connection Lost");
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
if not exists there will be nothing to check in that database

Firebase setOffline() and reading offline data (android)

Following situation:
User not registered, I save data while offline (Firebase setOffline())
Cannot read the local data (populate listview etc) - the ValueEventListener and ChildEventListener dont fire
I set setOnline() on Firebase instance
Data is synced with web and displayed (listeners fire)
I set setOffline() again.
I save local data and read local data, works (listeners fire)
Question:
How to read local data stored BEFORE going online?
Scenario is: User uses the android app offline and decides later to register
Scenario 1:
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
FirebaseDatabase.getInstance().goOffline(); // <--------NOTE THIS
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("users").child(App.get().getUid()).child("items").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// THIS IS NOT FIRING
}
#Override
public void onCancelled(DatabaseError databaseError) {
...
}
});
After Scenario 1 I change code to this and run:
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
FirebaseDatabase.getInstance().goOnline(); // <--------NOTE THIS
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("users").child(App.get().getUid()).child("items").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// THIS IS FIRING. ALL GOOD
}
#Override
public void onCancelled(DatabaseError databaseError) {
...
}
});
After this I change code to following and it works
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
FirebaseDatabase.getInstance().goOffline(); // <--------NOTE THIS
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("users").child(App.get().getUid()).child("items").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// THIS IS FIRING. ALL GOOD
}
#Override
public void onCancelled(DatabaseError databaseError) {
...
}
});
I added 3 segments (code blocks).
I execute first block - does not work
Second block - works
Third block - works
Here is a gist with the code.
Problem is that first block does not work before being online with setOnline()
Since you force the client to go offline in scenario 1 before it has a chance to synchronize any data, I indeed expect it to not fire onDataChange() in that scenario. In the 3rd fragment it will fire, because it has had a chance to synchronize data to the local cache.
But why are you explicitly trying to manage online/offline state? By doing this you're digging a hole that you may find it hard to get out of.
If you want to avoid having the user sign-in, you can start off with Anonymous Authentication and then upgrade that to a email/password or social account later.
Just keep in mind that starting offline and only enabling synchronizing later is not an ideal way of working with the Firebase Database, which is primarily an online database that continues working offline.

Retrieving firebase data to android

i try to make android app by retrieve temperature and hum data from firebase
json
how to show the data to textview android?
and how to show the latest inserted data from firebase.
thanks
UPDATE
i try this
code
can you give me an example to show the data to android please?
thanks for your help
What you need here is a ValueEventListener. In the fragment/activity that displays your TextView, you can add a ValueEventListener to a firebase reference like this:
// Get reference to firebase location where the data is stored
final Firebase databaseRef = new Firebase(Constants.FIREBASE_URL);
databaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(LOG_TAG,"ValueEventListener:onDataChange: " + "Data has changed");
// Get data
String temperatureData = (String) dataSnapshot.getValue();
// Update UI elements here...
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e(LOG_TAG,"ValueEventListener:onCancelled: " + firebaseError.getMessage());
}
});
Whenever the data at the specified location changes, the onDataChange() callback is triggered, so the UI is always up-to-date. Very powerful.
As someone new to Firebase myself, I can recommend this Udacity course : https://www.udacity.com/course/firebase-essentials-for-android--ud009

Firebase Realtime Database will not update after waking from Doze mode on Android 6.0

I've been working on an Android app that pulls data from a Firebase Realtime Database and fills a RecyclerView with information. It updates just as it should until the device goes into doze mode. When it wakes from Doze mode, the information does not reload. I have to force close the app and re-open it to get the latest information since the device went in Doze mode.
I've added in a "pull to refresh" with various attempts to force reload the data but it seems to just pull from the (outdated) cache on the device that Firebase makes.
Here is the function I use in a fragment to load the information from Firebase
public void loadTweetsFromFirebase() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference tweetsRef = database.getReference("rumourTweets");
Query query = tweetsRef.limitToFirst(100).orderByChild("timestamp");
query.keepSynced(true);
if (listener != null) {
tweetsRef.removeEventListener(listener);
}
tweets.clear();
adapter.notifyDataSetChanged();
listener = query.addValueEventListener(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot obj:
dataSnapshot.getChildren()) {
Tweet tweet = obj.getValue(Tweet.class);
// The keys are the tweet ids for the initial tweet, so we need to re-construct one with the obj key as the tweet id
Tweet newTweet = new Tweet(tweet.getCategory(), tweet.getProfileImgURL(), tweet.getTagName(), tweet.getText(), tweet.getTimestamp(), tweet.getUserId(), tweet.getUserName(), obj.getKey(), tweet.getRetweetedTweet(), tweet.getQuotedTweet());
tweets.add(newTweet);
adapter.notifyItemInserted(tweets.indexOf(newTweet));
}
refreshLayout.setRefreshing(false);
progressBarLayout.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("FB", "getUser:onCancelled", databaseError.toException());
}
});
}

Categories

Resources