30

When using Firebase Auth Anonymous Account it occasionally creates a new UserID in the system and sometimes it uses the same UserID. I really want this to create the same UserID every time so the anonymous user can still maintain the same progress/data in the app. This is actually the reason I started using Firebase for this feature. How can I always maintain an anonymous account to keep the same UserID even after relaunching the app, etc.?

I want the user to always get the same ID every time they play as a guest. There are apps that I have seen that even persist after uninstalling/reinstalling. What are the situations in which the user will get a new ID?

Edit: After implementing firebase Auth as suggested it will maintain the Anonymous UserID unless I completely uninstall the app and reinstall it. Then the Anonymous UserID is no longer detected which means the user will no longer have their Guest game data. Also, suppose the user is signed in as a guest and chooses to log out (ie. auth.Signout()) then they will also not be able to access their original Guest game data again. Am I still missing something here or does Firebase Auth not achieve my original intentions?

abdou_dev
  • 47
  • 5
user7431543
  • 421
  • 1
  • 5
  • 11
  • 8
    Anonymous authentication tokens do not expire and are persisted to disk between runs of your app. You will only get a new UID if your app calls `signInAnonymously()` multiple times. But it's hard to be sure without seeing the [minimal code that reproduces the problem](http://stackoverflow.com/help/mcve). – Frank van Puffelen Jan 19 '17 at 04:30
  • 1
    Thanks Frank. I updated my question with how I've been signing in guest. It may be my fault in tests. I just want to make sure it should behave as I expected. – user7431543 Jan 19 '17 at 04:52
  • 1
    If you call `signInAnonymously()` you're signing in a new anonymous user. You should only do that when there is no currently signed in user. What platform are you using btw? – Frank van Puffelen Jan 19 '17 at 04:55
  • @Frank I may have made anonymous sign in calls before signing out other auth methods while I've been testing this out. Currently using Unity Android. Would like to have the same effect in iOS down the road. SignInAnonymously should only create a new user if they have never signed in anonymously before. If say, they have signed in with facebook before and signed out. Then next launch they sign in anonymously I expect it will create them an anonymous account as well. I may have to scrap firebase auth if it doesn't maintain the same guest account everytime. – user7431543 Jan 19 '17 at 05:10
  • Unless the Unity SDK is different from all other Firebase SDKs: calling `SignInAnonymouslyAsync` will create a new UID. You should [monitor authentication state](https://firebase.google.com/docs/auth/unity/manage-users#get_the_currently_signed-in_user) and only call `SignInAnonymouslyAsync` when there is no signed in user. – Frank van Puffelen Jan 19 '17 at 14:57
  • 2
    Maybe I'm not understanding this correctly. I can't have a user maintain an anonymous userid throughout every launch of the application? Without storing anything on their local device. Other applications are able to do this so that the guest account will always maintain it's data... – user7431543 Jan 19 '17 at 17:22
  • 1
    You *can* have a user maintain their login. It happens automatically. But every time you call `SignInAnonymouslyAsync`, you're creating and signing in with a new anonymous user account. To pick up the *existing* anonymous user's info, you should monitor their authentication state (link in previous comment). – Frank van Puffelen Jan 19 '17 at 17:58
  • Sorry if this has already been covered. For web, android and iOS, once you sign in anonymously, the user should persist. Calling sign in anonymously again would return the same user. Unless you signOut the user or delete it, the user will persist. If the app is uninstalled or data is cleared, the anonymous user state will be lost and a new one created the next time. – bojeil Jan 20 '17 at 06:46
  • 1
    @bojeil thanks for clearing that up. that is unfortunate. if I store the users Token or UserID on my server can I use that to login an anonymous user again? I'm really curious how other apps are able to maintain guest accounts.. they have to be getting a unique id from each device based on MAC or something.. – user7431543 Jan 20 '17 at 14:24
  • I don't want to recommend this as this could easily be faked and phones are recycled and could exchange owners. If you store the UID of that anonymous user, you could theoretically restore that user via custom auth login. However, you need to make sure it is the same user. you need a unique trusted device identifier that you send to your server along with the ID token when the anonymous user is first logged in. This is not reliable. I suggest sticking to the current behavior that Firebase Auth provides out of the box. Please ignore my previous answer. – bojeil Jan 22 '17 at 03:11
  • I'm stuck with same problem as yours. Please let me know if you managed to get around sing-out and un-installation problem? – m-bhole Sep 16 '18 at 10:41

4 Answers4

4

So, in my case I wanted to show a login screen with signup but also the option to Skip login. If the user skips the login multiple times, I was doing signInAnonymous which I though it was reusing the user, but no.

So I solved it like this:

componentDidMount() {

    this.unsubscriber = firebase.auth().onAuthStateChanged((user) => {
      this.setState({ user: user, loadingUser: false}, () => {
        if (this.state.user != null && this.state.user.isAnonymous == false)
          this.startApp();
      });
    });

  }




skip = () => {
    this.setState({loading: true}, () => {
      if (this.state.user != null && this.state.user.isAnonymous == true)
        this.startApp();
      else {
        firebase.auth().signInAnonymouslyAndRetrieveData().then((result) => {
          this.setState({user: result.user}, () => {
            this.startApp()
          })
        })
        .catch(err => {
          this.setState({loading: false});
          alert(err)
        });
      }

    });

  }

Code is React Native but it should help you see the logic. I wait for the auth state and store the user temporarly. If it is not anonymous I start the home screen. If it is anonymous I give the user the option to register. If it still wants to skip, then I just start the app so I can re use the ID.

sebastianf182
  • 9,844
  • 3
  • 34
  • 66
4

You can use the Custom Auth System. Since the "Play as Guest" will only be specified for a special device. You can use Device ID as the CustomToken and then call Firebase Authentication Method:

auth.SignInWithCustomTokenAsync(custom_token).ContinueWith{.......

You can provide "custom_token" as the Device ID. You can get Device ID by:

string deviceID = SystemInfo.deviceUniqueIdentifier;

Hope this helps...

Faizan Khan
  • 207
  • 1
  • 14
  • I believe using that on Android will require permissions that wouldn't be acceptable. However, it looks like it is consistent for Android devices. From what I read, iOS will not be consistent and return a different id between installs. Thanks – user7431543 Jun 23 '19 at 23:52
  • I actually get Device ID on an app. Yet it didn't ask for permissions on Android. Maybe I was trying this with Debug Build instead of Release. Didn't know about iOS. So, if iOS returns inconsistent ids. I think this is not a solution for iOS then. – Faizan Khan Jun 24 '19 at 21:26
3

When you call SignOut, your guest will signout forever. If you want to keep your guest, don't call SignOut method.

milennium9
  • 39
  • 3
  • For example I don't call SignOut. I restart the game and Anonim login resets. Btw fixed by SignInWithCustomTokenAsync. – Eloren Oct 14 '20 at 19:02
0

Not sure if it's the best way to go, but you can create a 'guest' email account and just add a user with that account (then use your email/password as env to protect them). When you log in as a 'Guest', just send those credentials, that way you can still sign out and progress will be saved when logged back in.