i have tried on completion listener , but i want to check when i press the close sesion button if there is no data left to upload, my problem is that when i press close sesion and go to my loginActivity again, data is still uploading to firebase, so i get a null error because it cant reach the user to post the last data, what i want to do is to put a listener on the close sesion button where i can check if that user id is done with uploads
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
//here i want to test if the user has finished uploading all before sign out
FirebaseAuth.getInstance().signOut();
mGoogleApiClient.disconnect();
finish();
}
});
return true;
}
});
You don't need to wait untill Firebase finish uploading to the database, you need to use a DatabaseReference.CompletionListener.
This interface is used as a method of being notified when an operation has been acknowledged by the Database servers and can be considered complete
This means that once your data was successfully writen on Firebase database server, then you can sign out.
Related
I am storing user FCM device tokens in Firebase. When the user logs in, the token is added to the user's profile like this:
if (FirebaseAuth.getInstance().getCurrentUser()!=null) {
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
DeviceToken token = new DeviceToken(instanceIdResult.getToken());
CollectionReference deviceTokens = mUserCollection.document(mSignedInUserID).collection("device_tokens");
deviceTokens.document(token.getTokenID()).set(token);
}
});
}
This works. However, I also want to delete that document when the user signs out. I am attempting to do so like this:
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
Log.d(TAG,instanceIdResult.getToken());
DocumentReference deactivatedToken = mUserCollection.document(mSignedInUserID).collection("device_tokens").document(instanceIdResult.getToken());
deactivatedToken.delete();
mAuth.signOut();
recreate();
}
});
Everything works in that method except for the actual deletion of that document, and the log statement confirms that the user's current ID matches the title of the document to be deleted. A simulation for a signed in user writing to that location returns allowed. What am I doing wrong?
Note that, with your code, the user is going to get signed out before the document is deleted. That's because the delete() is asynchronous (as well as all database operations), and returns immediately, before the work is complete. If I had to guess, I'd say that your authentication token is getting wiped out before the delete operation actually gets sent, and the delete is effectively acting as an unauthenticated user. So, what you should do is wait for the delete to complete for actually signing out the user. Use the Task returned by delete() to know when that finishes. It'll work the same way as the Task returned by getInstanceId().
i was try to create login session with session key, the session key always generate new key either we do Login/registration, i can retrieve the data from my gson
LoginService loginService = retrofit.create(LoginService.class);
Observable<LoginResponse> obs = loginService.logins(emai,pass,"1", Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID), Build.MODEL, Build.VERSION.RELEASE);
obs.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).
subscribe(new Observer<LoginResponse>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
public void onNext(LoginResponse loginResponse) {
int responses = loginResponse.getCODE();
String texts="";
if(responses == 1)
{
User user = loginResponse.getDATALIST().get(0);
setPrefIsLogin(true);
setPrefSessionUid(user.getSESSIONKEY(),user.getUSERID());
nextActivity();
}
else{
}
}
});
the question is, how to make handler to handle the save session check if there is another login activity with the same account?
You should never assign two accessToken/Session for one user. You will send the same accessToken to the other instance of the new user. Plus side, user won't be able to duplicate his/her work by two accessToken.
If you want to force the other/first one AUTO-LOGOUT, you can use Firebase notification feature to send a notification to that particular deviceID and force it to stop. You can check firebase's tutorial to see how they work.
Another slow procedure is to check before login & everyother server side work to check if there are instance of same user. You will send an error and user end will receive it and show the error accompanying by logging out the user.
I am using Google Sign in for authentication. Following the tutorial, I am able to log in. Now I want to log out the user. I got the code for logging out. But how to do I know that the logout is success or fail?
private void signOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
// What code should I write here to see if the user has successfully logged out. If not, then I need to display an error message.
}
});
}
Google can return 5 types status. Following are the statuses along with the status codes:-
SUCCESS(0), INTERNAL_ERROR(8), INTERRUPTED(14), TIMEOUT(15), CANCELED(16)
So you can check for status.getStatusCode() on logout and validate against the above mentioned statuses.
Just use
status.toString()
and log it to find out what details it contains. Then according to it you can use the below methods to check if you have been successfully logged out.
status.getStatusCode();
status.getStatusMessage();
Both methods are self explanatory.
I found a better approach to the question
Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
// user logged out successfully
} else {
// the logout was not sucessful.
}
});
I am creating an app on Android that uses Firebase as database and Batch for pushing notifications. Usually, when my app starts, it goes to the main page, a login activity. The activity verifies if a user is still logged in using:
Firebase dbRef = new Firebase(Constants.URL_DB);
AuthData auth = dbRef.getAuth();
if (auth != null) // Proceed with a logged in user
else // Show authentication layout
My problem is that when I get a notification from Batch, I click on the notification to go to the app but then I am not logged in as I should be... auth == null. I don't want my users to need to log in every time they get a push from Batch. Can I detect that the app started from a notification? How is that I lose authentication from Firebase?
Here is the onCreate and onResume of the MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initiating Batch
Batch.onStart(this);
// Initiating layout
setContentView(R.layout.login);
// Setting database
Firebase.setAndroidContext(this);
// Unrelated stuff done here (Setting Views, etc)
}
#Override
protected void onResume() {
super.onResume();
// Getting login information from previous authentication.
Firebase dbRef = new Firebase(Constants.URL_DB);
AuthData auth = dbRef.getAuth();
// I added the addAuthStateListener here
if (auth != null) {
goToHomePage();
}
}
All right I found the problem. When I click on the notification, my MainActivity is called obviously. The thing is that when the user is logged in successfully, I start another Activity using:
startActivityForResult(intent, Constants.SUCCESS);
Now, onActivityResult is normally called to log out the user when the back button has been pressed on the home page. Otherwise, onResume is called and since the user is logged in, I would go straight back to the home page. BUT: when I click on a notification, somehow onActivityResult is called (probably because the activity stack gets trashed) and the user is logged out before resuming the activity.
So the solution is to log out the user in the onBackPressed of the home page activity. Then I don't need to startActivityForResult anymore.
// In the home page activity
#Override
public void onBackPressed() {
super.onBackPressed();
Firebase dbRef = new Firebase(Constants.URL_DB);
dbRef.unauth();
finish();
}
I'm starting to use Backendless.com mBaaS on Android
I sign in user via Google and I got token and everything is OK, but the logged in user isn't created an Users table, so I can not use it to store user specific data.
So I tried to combine user login from here with user creation from documentation:
if (result.isSuccess()) {
logined = true;
loginInBackendless(result.getSignInAccount());
BackendlessUser user = new BackendlessUser();
user.setProperty("email", result.getSignInAccount().getEmail().toString());
user.setProperty("name", result.getSignInAccount().getDisplayName().toString());
user.setPassword(UUID.randomUUID().toString());
Backendless.UserService.register(user, new AsyncCallback<BackendlessUser>() {
public void handleResponse(BackendlessUser registeredUser) {
// user has been registered and now can login
}
public void handleFault(BackendlessFault fault) {
// an error has occurred, the error code can be retrieved with fault.getCode()
}
});
the question is:
Is it right way to create user? it seems not OK, because every time google user is logged in, a new Backendless user is created (or his record in Users table is updated).