I am currently building an app that saves the user's blog post in Firestore
server. Everything is working fine, but I found out that the post was not uploaded under the unstable internet connection.
I tried to set a timeout to the Firestore
instance, but it seems like there's no timeout option for Firestore library. The problem is, because there's no timeout setting, the app doesn't know when to dismiss the uploading screen (Spinner dialog).
I was thinking about creating a Handler
or Observable
or Thread
and setting the timeout manually. After the specified timeout period, let the app dismiss the uploading screen. However, Firestore client will keep retrying the upload in the background even after the timeout. So this approach won't be suitable for this case...
Is there any solution for this? If I can set the timeout for the Firestore client itself, meaning letting the client to call onFailure()
after the given timeout period, I can just save the post as draft in the local storage and try it again when the device is back to stable connection.
Firestore will immediately add the document to its local cache. It will then try to synchronize that document with the server. To detect whether it will be able to do so, have a look at Gastón's answer.
To detect when the document has been written to the server, use a SuccessListener
. This example from the Firestore documentation on adding documents shows how:
// Add a new document with a generated id. Map<String, Object> data = new HashMap<>(); data.put("name", "Tokyo"); data.put("country", "Japan"); db.collection("cities") .add(data) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { Log.d(TAG, "DocumentSnapshot written with ID: " + documentReference.getId()); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.w(TAG, "Error adding document", e); } });
The best way of doing this is attaching a boolean that will let you know if you have internet before doing something (this is just to dismiss your spinner, as firestore has offline features like realtime database)
public static boolean hasActiveInternetConnection(Context context) {
if (isNetworkAvailable(context)) {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1500);
urlc.connect();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
Log.e(LOG_TAG, "Error checking internet connection", e);
}
} else {
Log.d(LOG_TAG, "No network available!");
}
return false;
}
so you should check first if you have an active connection , this method will ping google.com and check for internet connection, if is not reachable after 1.5 seconds it will return false
so you should do something like this (pseudocode)
if(hasActiveInternetConnection)
doyourfirebaseuploadstuff
else
spinner.dismiss()
Toast(please check your internet connection and try again)
Remember to add your internet permissions in your manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
EDIT:
Another cool method and maybe more readable for someones can be this one
public boolean isInternetWorking() {
boolean success = false;
try {
URL url = new URL("https://google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.connect();
success = connection.getResponseCode() == 200;
} catch (IOException e) {
e.printStackTrace();
}
return success;
}
it just works like the other one , instead that this will just wait for 10 seconds untill it returns the internet status
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With