Firebase Realtime database has a function goOffline, goOnline which can manage the connection manually. But, Firestore doesn't have these methods.
Does Firestore return exception something like NETWORK_ERROR when device lost connection with server? If it doesn't, how can I manage Firestore connection manually when device can't connect to internet and reconnected. (e.g. Airplane mode, Bad wifi)
In my case, I don't use persistence mode.
Does Firestore return exception something like NETWORK_ERROR when
device lost connection with server?
You have use addOnFailureListener which uses OnFailureListener that can just gives you an Exception object to find the cause or message behind the exception via getCause or getMessage and further can apply String checks like contains etc to verify the cause but currently there is no standard way provided by FirebaseFirestore.
how can I manage Firestore connection manually when device can't connect to internet and reconnected. (e.g. Airplane mode, Bad wifi)
You can check the connectivity yourself also at desired places before executing firebase code
Related
I am using Firestore in my app. According to the documentation, it supports offline data persistence and when the network is on again, Firestore synchronizes changes.
Here is my code.
FirebaseFirestore db = FirebaseFirestore.getInstance();
User user = new User();
db.collection("users").document("doc").set(user);
It works as expected: it caches locally if the network is off and synchronizes when the network is on again. But I keep getting this warning:
W/ManagedChannelImpl: [{0}] Failed to resolve name. status={1}
This post says it is due to no internet connection. If Firestore supports offline persistence, why do I get this warning? How to get rid of this warning?
It works as expected: it cashes locally if the network is off and synchronizes when the network is on again.
That's the expected behaviour.
But I keep getting this warning:
W/ManagedChannelImpl: [{0}] Failed to resolve name. status={1}
This post says it is due to no internet connection.
That post it right, it's because of no internet connection.
If Firestore supports offline persistence, why do I get this warning?
You get it because between the time when you regain the internet connection and the time when the listener actually becomes active, there is an amout of time in which your client is not connected to the server. That's the reason why that warning is printed out multiple times without stopping unless the network is on and the client is synchronized again with the server.
The reason that the retries aren't happening so quickly as you expect is because the code that performs the retries is using a so called exponential backoff algorithm. This means that this code prevents all the retries that can happen on user's device so quickly in favor of performance. Too many retries can also affect the user by consuming too much bandwith of the his data plan.
When you are listening for changes in a Cloud Firestore database and you have some network disconnects, this what is happening and unfortunately there isn't much you can do. You don't have any control on how Firebase Firestore SDK manages its connections.
How to get rid off this warning?
IMO, since it's only a warning and not an Exception and it is displayed only for a few seconds till the connection is reestablished, you can simply ignore it.
But if you really want to get rid of it, the code below might help you. Please note, that I haven't tested yet.
InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder()
.setKeepAliveTime(Duration.ofSeconds(60L))
.setKeepAliveTimeout(Duration.ofMinutes(5L))
.build();
FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder()
.setChannelProvider(channelProvider).build();
FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
.setCredentials(credentials).setFirestoreOptions(firestoreOptions)
.setConnectTimeout(5000).setReadTimeout(5000).build();
FirebaseApp firebaseApp = FirebaseApp.initializeApp(firebaseOptions);
Firestore firestore = FirestoreClient.getFirestore(firebaseApp);
I have two apps
Client App
and
Server App
in android
What i want
To check in my server app that weather client app has internet connection or not.
What i have done
I had read this post
I have used BroadcastReciever to Listen weather internet is available or not. All is well. When internet connection goes right , i am saving value online to Firebase "true"
But
When internet connection goes off ,
i am using Firebase onDisconnect() method to save ServerValue.TIMESTAMP
It works sometime in two minute but sometime it doesn't update firebase and value remains true.
Note what i want when client app is connected ,on firebase it should save true and when it is not connected it should save false . Though in my server app i will retreive those values to show to client is online or offline
is there any other technique to do such a scenario in android ?
What do you suggest any improvement in my current scenario. ?
Help will highly appreciated.
Thanks
leave this onDisconnect(), write an API that will do nothing but will just ping the server after a fixed time continuously, let's say after each 2 seconds the API will be called(through service), so in case the net is disconnected or the cell phone is even off, since API will not respond to the server, here you will write a code in case app did't ping to the server after 2 seconds(or you can say after 5 seconds), the response(online status) should be FALSE automatically!
so in case the app is again connected to internet, since the service is running so service will update your false into TRUE again
that's too simple!
i think this is your required function!
I want to change user status to show either he is online or not. I want to change user status to false in database when User close application or when he loses connection with server.
As a method is available named as onDisconnect() .I have used that method to update user status by using following code .
HashMap<String,Object> user_online_status=new HashMap<String,Object>();
user_online_status.put("online",true);
DatabaseReference firebaseDatabase=FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
firebaseDatabase.updateChildren(user_online_status);
//then to show user offline
user_online_status.put("online",false);
firebaseDatabase.onDisconnect().updateChildren(user_online_status);
I do that task but as it is on client side and If we want to monitor user connection with server and when connection is terminated node should be updated by Server Instead of Client.How can we change node value from server as User lose connection with server?
There are two ways the user can get disconnected from the Firebase Database.
a clean disconnect, where the client sends a signal to the server before it disconnects.
a dirty (for lack of a better term) disconnect, where the connection gets closed before the client can send a signal.
In the case of a clean disconnect, your onDisconnect handlers will immediately fire and thus your database will immediately be updated.
In the case of a dirty disconnect, Firebase depends on the socket layer to signal when the remote client is gone. This may take anywhere up to a few minutes. But eventually the server will detect/decide that the client is gone, and your onDisconnect handlers will fire.
A small note in your data structure: you that there is a 1:1 relation between a user and a connection. That is unfortunately not the case.
A user may be connected from multiple devices. If they now disconnect from one of those devices, the onDisconnect from that device will set online to false while they may still be connected on another device.
Mobile devices/networks have a habit of going through occasional disconnect/reconnect cycles. This means that you may have multiple connections, even on a single device. In case of a dirty disconnect, the onDisconnect handler may be fired much later, when you've already set online to true for the new connection. In such a case, your lingering onDisconnect handler will set online to false while the user may already be reconnected.
All this is to say that you should not rely on having a 1:1 relation between a user and their connection(s). The samples in the Firebase documentation treat connections as a collection and assume that the user is connected as long as there is any "connect ID" (generated by push()) left for that user. I recommend you do the same to prevent hard to debug race conditions and connection problems.
I am attempting to get Google Nearby API working on my handset (an s5).
I am building and running the stock project from github Google Nearby API GIT.
The app builds and runs, with no errors. Having exported the app onto two S5s (amongst other handsets I have attempted to test it with) and connecting to a WLAN from a D-Link DSL-3680. Multicasting is enabled and set to v3.
However the app refuses to connect with the neighbouring phone when corresponding 'advertise' and 'discover' instructions have been given.
Is there an effective way in which to debug this behaviour? If I can provide an effective information dump of information that might help someone identify the issue then please let me know how.
What do you mean by 'refuse to connect'?
are you getting connection status- 'Rejected'?
If you are able to advertise and discover other devices, I'm assuming all your base conditions (like connected to local network) are fulfilled
Now,
You can try logging your status in Connection call back when you try to connect
Nearby.Connections.sendConnectionRequest(mGoogleApiClient, myName,
remoteEndpointId, myPayload, new Connections.ConnectionResponseCallback() {//response conditions}
using--
inside connection callback function write
if(status.isSuccess()){
// Successful connection
} else {
// Failed connection
}
similarly, if you are not doing this, you need to accept the connection request
Nearby.Connections.acceptConnectionRequest(mGoogleApiClient, remoteEndpointId, myPayload, this)
and inside Onresult callback add-
if(status.isSuccess()){
// Successful connection
} else {
// Failed connection
}
Hope it helped
I create a monitoring application who :
if there is a network connection available : she sends periodically
measurement data to the server using json
if there is no network available, she stores the data in the sd card and sends it when the network connection is back.
Actually I use a circular buffer in memory that I empty when data are sent
Is there already something usefull in the framework or I have to write that completly ?
Thanks
I would check tape library from square. I've never tried it but looks what you are looking for.