Reputation: 173
I have implemented a simple timeout system for requests to my Realtime Database.
private void makeRequestWithTimeout(final int timeout, final DatabaseReference reference, final OnTimeoutRequestListener listener) {
Thread thread = new Thread() {
boolean connected = false;
boolean exited = false;
@Override
public void run() {
reference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (!exited) {
listener.onSuccess(dataSnapshot);
connected = true;
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
if (!exited) {
listener.onFailure(databaseError.toException());
connected = true;
}
}
});
try {
sleep(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!connected) {
listener.onFailure(new Exception("Timeout, request exceeded " + timeout + "ms timeout"));
exited = true;
}
}
};
thread.start();
}
I need this because I want to check if for example a username is already taken, and I don't want to proceed if I can't get a value from the db.
Okay so I thought this works pretty good but following scenario doesn't work:
When I'm in airplane mode and make a request, the timeout exception fires as expected. Then I disable airplane mode and make another request. I get another timeout exception.
EDIT: this goes on for 2 minutes, until a request is successful again.
Turning on Database logging, it seems that it doesn't even try to get the value.
I've also read this.
Is there anything I can do about it?
Upvotes: 0
Views: 4015
Reputation: 38299
When I run your code with version 10.0.1, I see the reported behavior except the delay before requests are successful again is only about 20 seconds.
It appears that when a connection becomes available after exiting Airplane Mode, it takes Firebase a short time to detect the change. You can see when Firebase recognizes the change by adding a connection state listener:
FirebaseDatabase.getInstance().getReference(".info/connected")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.getValue(Boolean.class)) {
Log.i(TAG, "Firebase CONNECTED");
} else {
Log.i(TAG, "Firebase NOT CONNECTED");
}
}
@Override
public void onCancelled(DatabaseError error) {
Log.e(TAG, "onCancelled: ", error.toException());
}
});
Upvotes: 2