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
Related
I'm creating an Android app for the first time, I've got a simple Realtime Firebase Database with a couple of records in it. I have the following code;
public void onStart() {
super.onStart();
// Read from the database
databaseMatches.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot matchSnapshot : dataSnapshot.getChildren()) {
matches match = matchSnapshot.getValue(matches.class);
matchesList.add(match);
}
matchList adapter = new matchList (getActivity(), matchesList);
listViewMatch.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
If I put a breakpoint on the databaseMatches.addValueEventListener(new ValueEventListener() { it shows me that the database connection has been set and is returning the correct object (In my view).
The challenge I have is the part after, the break points for public void onDataChange nor onCancelled ever get hit. I'm lost here and not sure what might be the next step as it appears to be connecting, but I am not able to retrieve records.
I'm doing this in a fragment instead of a activity. Any help is appreciated.
Detecting Connection State
it is useful for your app to know when it is online or offline. Firebase Realtime Database provides a special location at /.info/connected which is updated every time the Firebase Realtime Database client's connection state changes. Here is an example: If you are not sure.
https://firebase.google.com/docs/database/android/offline-capabilities#section-connection-state
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");
}
Firebase also loads and synchronizes data asynchronously
see Setting Singleton property value in Firebase Listener
Thanks.
There must have been some strange caching issue as the following morning when I ran the exact same code, no problem. And I've not had a problem since.
I'm making an app and I've run into a problem with Firebase's Database and Authentication services.
After a while, while I am authenticated (using Firebase Auth) and using my app, my database ValueEventListeners don't seem to be called, even though there is data in the database.
How I'm adding my listeners:
FirebaseDatabase
.getInstance()
.getReference()
.child("my_child")
.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Log.d("App", "onDataChange");
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
});
Stuff I've tried:
Checking the database rules (after a relog reading is fine - but simulated reads pass even while authenticated & unauthenticated)
keepSynced(true) on the DatabaseReferences
Adding the listeners in the Activity's onCreate instead of the Application's onCreate
Adding/removing/updating data in the database to trigger a sync
Rebooting
Any help would be much appreciated.
So, apparently the issue was that an API called "Token Service" was not enabled in my Google APIs dashboard.
Thanks to a helpful email from Firebase Support (thanks guys!), I've turned on debug logging by calling FirebaseDatabase.getInstance().setLogLevel(Logger.Level.DEBUG);
Lo and behold: D/PersistentConnection: pc_0 - Error fetching token: An internal error has occurred. [ �Token Service API has not been used in project <project-id> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/securetoken.googleapis.com/overview?project=<project-id> then retry.
So by enabling the API, it seems to have fixed the error!
Create a reference to your child database, create a custom Chat class as per your requirement( essentially what you see in your firebase ).
addChildEventListener should give you all the changes happening with your my_child. Hope this helps you.
mFirebaseRef = new Firebase("https://yourapp.firebaseio.com/").child("my_child");
/**
* Firebase - Receives message
*/
mFirebaseRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try{
Chat model = dataSnapshot.getValue(Chat.class);
mChats.add(model);
mRecyclerView.scrollToPosition(mChats.size() - 1);
mAdapter.notifyItemInserted(mChats.size() - 1);
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
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.
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());
}
});
}
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());
}
});