I'm implementing Google Smart Lock into my app. I've got it logging the user in automatically with a single account and it works well.
However, once I add a second account to the mix it always shows the resolution dialog to pick which account I want. This continues to show even after I have selected and account and restarted the app.
This dialog shouldn't show anymore once I have selected the account I want smart lock to use, so what are some possible reasons for it still showing?
-Thank you
I work on the Smart Lock team at Google, hopefully this answers your question:
as you note, if the CredentialsApi.request() API method is called and there are multiple saved accounts for the app, stored in either one or multiple Google Accounts on the device (or auto sign-in has been disabled by the user for one of their accounts or by the developer by calling CredentialsApi.disableAutoSignIn()) then the API will call back with a CredentialRequestResult with getStatusCode() of RESOLUTION_REQUIRED, meaning that UI must be shown for the user to pick a credential to continue. startResolutionForResult() will show the dialog, as described in the API overview.
once the app has a credential, either from auto sign-in or after the user has selected one from the dialog, most apps will use this credential to sign the user in to a backend service and establish a session with a cookie or token for the app and manage this independent of the Smart Lock API. Thus, most apps won't call the API again after the user has signed in and a current session exists, hence the dialog won't be shown again after the initial sign-in.
when the user signs out, calling CredentialsApi.disableAutoSignIn() will prevent the user from being automatically signed back in when the authentication activity is started again, and the disabled state is automatically managed and cleared when the user selects an entry from the credential picker UI or a successful CredentialsApi.save() call is made, and at this point, a user session is established and there is no need to call the API again until a sign-out event.
I think the confusion in this question stems from calling the API after the user has signed in and they might already have an active session. Was that your intent? If you need to manage credentials of the app on the device after a password has been retrieved or input by the user, you can use the Account Manager on Android, which is independent of any Google accounts or APIs (whereas Smart Lock is geared toward saving sign-in info in the cloud for use across platforms on new or separate devices to bootstrap the auth process).
In the future, we are considering remembering a user preference if multiple accounts are stored and the same one is always picked, thereby allowing automatic sign-in, but right now, user action is always required when there are multiple saved accounts available.
Do leave a comment with any questions or feedback if you need more info or clarification or if this doesn't answer your question!
When you have multiple account, you will always show this resolution dialog.
Look this :
from : https://developers.google.com/identity/smartlock-passwords/android/overview
Related
I am trying to understand if Google Play allows "Delayed Consumable Items". Something I made up:
Allow user to purchase a Golden-Key (for example).
This Golden-Key will be repurchasable when it loses its shape.
It should be valid on all the devices that is being used with the same Google Play account.
It must not require a brand new membership system that works on my own server.
It must not require me to query for the primary account on the device.
Technically:
Normally, I can always keep track of a non-consumable purchase as Google keeps it forever and as soon as user restores the purchases, all of them will be available for me on any device user have.
Things get tricky if I also want to add consumable items which I do not want to consume right away as consuming it will prevent me from tracking that purchase on other devices of the same user or if the user reinstalls the app. I can do it by first registering an account on my server and saving the consumed item on that account, but I do not want to show the user a signup or login system. I can also do it by retrieving the primary user account on the device and save it serverside, but I do not want to frighten user by requesting permission to those APIs.
So, I noticed that "I" am the person who manages the in-app items on the documentation, but I am not sure if I can assume the following:
- Let user buy an in-app item, but do not consume it until the user wants to purchase another one which may happen even after 3 years. (I will keep the order id on my server and prevent the user from accessing certain things if I mark that order id as used serverside. So, the user will intentionally hit "replace" button in the app and that button will consume the current in-app and start a new transaction.)
To cut it short, maybe I could summarise it in 1 sentence:
Can I consume an in-app item even after (for ex) 3 years, like a manual non-autorenawable subscription system where the duration is variable?
I've implemented Firebase Invites as described in the documentation and it works fine.
I've discovered that if a user has multiple Google accounts then the first time the Intent is invoked, Firebase asks the user to select one of these accounts (if they choose to send an invite via email, the selected account is the one it comes from).
However, my users have complained that that there is no way to change the account that is used. Uninstalling the app and reinstalling does not cause the prompt again, so apparently Firebase is storing the selection internally.
I've found the setAccount method, but that would require me to launch the account-chooser dialog and specify the Account every time. I was hoping there would be some mechanism to cause Firebase to reset the choice that it has stored internally. Is there a way to do that?
Note that calling FirebaseAuth.getInstance().signOut() has no effect. In fact, calling FirebaseAuth.getInstance().getCurrentUser() returns null. That seems to confirm that Firebase Invites is not using Firebase Auth. [It would be nice if Google documented what is going on, instead of us having to guess how it works.]
Here's the private response I got from a Google engineer:
No, there's no way to clear the default account. As they mentioned, setAccount would be the recommended way to choose the account. For this case, though, you might want to tell them that the user actually can change the account from the Invites screen by tapping on the user avatar. If they have more than one account on the device, this should bring up the account chooser to change what account emails are sent from.
Im developing an android application for the first time (no prior experience whit coding....). Mainly the app is going to be used at work as a tool for service technicians. The app is almost ready for field testing, but there is one thing i need the app to do before that. I need the app to force the user to log in every time its opened. This is because some of the info on the app is confidential, and only people that currently works for the company is allowed to have this info. Whit firebase i can then block the users that leave the company, or users that are not verified. Currently the users sign in whit google and they stay signed in until they clear the app data or delete it.
I have looked far and wide for the answer to this, but i have only come across different use of timers.
If anyone has a better solution to this "safety" issue, im open to anything.
If you are using Google Sign-In for authentication, there is no out of the box support for forcing your user to authenticate with Google every time they use your app.
This makes sense, because the user is still authed with Google on your phone. A login system only authenticates the user; it doesn't inherently protect data stored on the device. As long as Google has a valid access token, the user won't have to type a username and password again (and simply clicking "login with Google" again doesn't really provide extra protection here).
If your primary concern is blocking access to users who have left the company, you should be covered if you are using Google Apps for your company. If you disable the user's account, their access tokens should become invalid. Google Apps admins can also manually revoke access to specific apps for specific users.
If you don't use Google Apps (e.g. your users are using #gmail.com accounts or accounts from a domain outside fo your control), you might want to consider implementing a list of users allowed to access the application, and verify the current user has access by checking that list via an API call on launch.
If the goal is really protecting the confidential information in the application, you might want to take an approach similar to Android Pay in which you require your user to set and enter a PIN number to access the application. As an added benefit, you can then use that PIN to encrypt any confidential data you are storing locally.
I will suggest you take a look into shared preferences and every time when the user is back into the app you send them to the login activity.
Google states in the documentation that "when the user signs out, call CredentialsApi.disableAutoSignIn() to prevent the user from being immediately signed back in (...)".
This is what happens:
User only has 1 credential stored. When he enters the app, he is automatically signed in;
User signs out, and CredentialsApi.disableAutoSignIn() is invoked;
Now, every time the user enters the app, instead of being automatically signed in, he is presented with a chooser, although the chooser only has 1 option, for the only credential stored.
This is very, very annoying. If the user logs out, he shouldn't be bothered every time to login again. Even if he has more than 1 credential. But, for the time being, let's focus on the case where he only has 1 credential.
Is this the expected behavior? I'm pretty sure that when I tested this feature in January, it wasn't like this. Now I'm putting this feature into production, and if this is the expected behavior, maybe I have to
store a flag in the shared preferences for detecting when the user logged out.
The request credential feature is in the main activity of the app, and every time I go there, the dialog chooser appears to request the login.
Unfortunately, you'll have to maintain user state in your app (we haven't made any changes to this behaviour recently, it's always been like this).
If sign-in is optional for your app, here's what we've seen some apps implement:
keep track of whether this is the first run on the device (e.g. in shared preferences), if so, trigger sign-in automatically and show the picker, allowing the user to sign in with one tap if the auto sign-in is disabled or they have multiple accounts
on subsequent app starts, you can still try for automatic sign-in (e.g. after user signs up on web or another device and then opens app), but don't resolve the result if it's not the first run (i.e. don't show the picker, just discard the Intent for resolution or hold it for later)
if the user explicit triggers the sign-in action (i.e. clicks a sign-in button), you can use the intent, or call the API again to help them sign back in to their account, or switch between accounts
Sorry, this requires a bit of state on your side; the CredentialsApi.disableAutoSignIn() sets the sign-in disabled state, but does not track the user's signed-in state to the app (which is dependent on the application developer's logic and has to be managed by the app).
Hope that helps / makes sense, feel free to leave comments. Will see if we can add some guidance to the docs for this!
I’ve implemented google+ sign in with the GoogleAuthUtil class using ‘Cross-client Identity’ method as described here. My app uses the following scopes:
http://picasaweb.google.com/data/
http://gdata.youtube.com
https://www.googleapis.com/auth/plus.login
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile
The first time a user signs in all the scopes are shown to the user in a single screen and clicking sign-in works fine. The trouble begins once the user has signed in for the first time; Any subsequent sign ins (logging out of the app and attempting to sign back in) leads the user to the following scenario:
User is presented with google permissions screen again (despite already having granted permission to this application for this account)
This time around (not first sign in) the permissions screen is split to two, the first one only shows the youtube scope:
The second one shows the rest of the scopes (including youtube again):
Does anybody know why the permissions screen is displayed again if the user has already accepted these scopes for this account?
More over why are the scopes split to two different screens the second time around?
You need to be careful when implementing that flow to avoid this problem. The important thing to know is that the request for the code (e.g. oauth2:server:client_id:CLIENTID:api_scope:SCOPES) will always require a consent dialog to be displayed. The proper flow you should use:
Retrieve an ID token for the user (this does not require consent)
Send this to the server to determine whether it requires a new (refresh) token for this user.
If the server has one, it should generate an access token from the refresh token
If it does not, the client should retrieve one, which will require the user to consent.
With regards to the double consent screen - will probably need to see your code to answer that. A common cause is retrieving an access token with GoogleAuthUtil, and then retrieving the code (the consent dialog already seen for the access token does not count for the code retrieval, so it causes another). Its possible there is an issue around the youtube scope, but retrieving multiple tokens feels most likely.