[SOLVED] Persisting the Facebook AccessToken between restarts?

Hi all -

I successfully implemented the Facebook SDK into my game (currently the App is set to development mode on FB). While I am able to log in just fine, I noticed that logins do not persist between hard closes - e.g., if I hard-close the app on iOS and Android and then open it again, I have to login anew. Other than that, everything is working fine - FB.Init runs on Start, checks for login, etc etc, basically as in the tutorials made available on Facebook’s Unity SDK page.

What I want to achieve is a solution where the user’s login status persists between hard-closes, without having to log in every time.

I have a Save() method running in OnApplicationPause() which saves player data via binary serialization. Should I use it to explicitly save the login token when the application is paused (e.g., data.accessToken = FacebookController.token)? I was under the impression that Facebook’s SDK was entirely responsible for managing the lifetime of the token, including its persistence, but I might be wrong on that point.

I’ve not seen this on iOS. I remain logged in all the time.

Presumably, without any special effort to save the Facebook token, right? I also wonder if the behavior is different for test mode and live apps - is your app marked as Live on FB?

1 Like

No special effort. Just using the default behaviour. App is marked as Live on Facebook.

Hm, I wonder if it’s got something to do with Live vs. Test status, then. Well, thanks anyway, will fiddle around and see what can be done.

I don’t recall it acting any different when I was testing but I could easily be wrong.

@GeorgeCH_1 And actually I just tested it on an app I’m developing and I remain logged in on that too - and it’s marked as Development on Facebook.

Thanks! At least now I know that I should be looking at my code. Will take a crack at it the evening.

Can you show us the code you’re using to login in/authenticate with facebook each time?

Do you have the facebook app also installed on this device?

On Android, think you also need to have your Key Hashes configured to have things run properly (not 100% on that though)

I am experiencing the same issue. My app will show a log-in prompt every time it connects, even if already authenticated. Did you find out what is causing this?

Howdy -

Here is the code - I did have the Android hash issue you mentioned but have since configured them so they’re working correctly. I do have the Facebook app installed on the iOS device, but not on the Android one.

Hm, now that I re-read the code, it’s entirely possible that, once again, I was a complete and utter numpty - nowhere do I actually see a line where I call FBLogin() in the Start() function, relying instead on a manually calling it by pressing the button. I’ll confirm when I get home tonight - but I am starting to feel increasingly sheepish…

EDIT: Or - and maybe this is the crux of the question - should FB.LogInWithReadPermissions be only ever called once per user per device (except in cases of expired tokens)? Or should be it called at the start of every session?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Facebook.Unity;

public class FacebookController : MonoBehaviour {

    AccessToken token;

    private void Start() { if (!FB.IsInitialized) { FB.Init(); } else { FB.ActivateApp(); } }
    public void FBLogin() { FB.LogInWithReadPermissions(callback: OnLogIn); }
    void OnLogIn(ILoginResult result)
        {
        if (FB.IsLoggedIn)
            {
            token = AccessToken.CurrentAccessToken;
            }
        else
            {
            }
        }
}
1 Like

Yeah, as long as you call the login code directly, it will relog in after the first time the user inputs their information and not prompt. However, if you do something like clear the cache, re-login is required with prompt.

Thank you! Just to make it sure I got it right, we still have to log in every single time the app is started - the difference is whether the user is confronted with the login screen (for first-time logins) or not (for subsequent logins). In other words, in the latter scenario, we still log in, but this all happens seamlessly for the user, who doesn’t even realize that a login happened under the hood.

Am I right? If so, I could just put FB.LoginWithReadPermissions into the start and/or OnApplicationPause(false) function and call it a day.

Correct. Example, we have a login scene that lets you choose FB, email, or just to go play the game. If you choose FB, it prompts you the first time. After that, we record in a playpref that FB has been chosen and it simply runs through the login process and the user doesn’t get prompted again. (there are ways to get prompted again, but for the general player, they should never see the login again).

You do not have to record the access token, FB ID, or anything else to avoid getting prompted again.

1 Like

Wonderful, thank you very much! I’ll try your solution out tonight and report back.

As promised, I’m happy to write back to report that the solution worked; moreover, that no explicit relogging into FB was necessary. As it turned out, the problem was not with my sessions persisting, but with FB-dependent buttons getting disabled for reasons that I thought were FB-related, but that were actually related to missing authorization checks for other services.

In case it helps anyone in the future, here’s the code I ended up using - note that it also includes provisions for syncing up with BrainCloud, which I use for leaderboard management.

Thank you to everyone to has contributed to helping me fix this!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Facebook.Unity;
using UnityEngine.UI;
using BrainCloud;
using BrainCloudUnity;

public class FacebookController : MonoBehaviour {

    public Image image;

    public delegate void Announcement();
    public static event Announcement OnFacebookLogin;

    private void Start()
        {
        if (!FB.IsInitialized)
            {
            FB.Init(onInitComplete: FBInitCallBack);
            }
        else
            {
            FB.ActivateApp();
            }
        }

    void FBInitCallBack()
        {
        FB.ActivateApp();
        if (FB.IsLoggedIn) { OnFacebookLogin(); }
        }

    public void FBLogin()
        {
        FB.LogInWithReadPermissions(callback: OnLogIn);
        }

    void OnLogIn(ILoginResult result)
        {
        if (FB.IsLoggedIn)
            {
            OnFacebookLogin();
            // FB.API("/me/picture?type=square&height=200&width=200", HttpMethod.GET, DisplayProfilePic);
            AuthenticateBCWithFacebook();
            }
        else
            {
            }
        }

    void DisplayProfilePic(IGraphResult result)
        {
        if (result.Texture != null) { image.sprite = Sprite.Create(result.Texture, new Rect(0, 0, 200, 200), new Vector2()); }
        }

    public void AuthenticateBCWithFacebook()
        {
        if (!BrainCloudWrapper.GetBC().Authenticated)
            {
            BrainCloudWrapper.GetBC().AuthenticationService.AuthenticateFacebook(
            externalId: AccessToken.CurrentAccessToken.UserId,
            authenticationToken: AccessToken.CurrentAccessToken.TokenString,
            forceCreate: true);
            }
        else
            {
            }
        }
}
1 Like

Hey there. I copied your code pretty much verbatim, and I am STILL getting the log-in prompt every time my app connects to FB (even though it is already authorized).

Is there a setting that I may have overlooked?
What is this “cache” that people mention?

What could possibly be causing this - I’ve been trying to track it down for two days with no success! :frowning:

Oddly enough, I don’t have this issue on Android…

Thanks in advance for your help.

The editor will always prompt for an access token. But android and iOS should only do it once.

@DanTaylor

Pretty much what Brathnann said - the editor will always show you the login screen where you have to enter the token, but that’s NOT how it will work on Android and iOS. In other words, it’s one of those cases where your Editor experience is not representative of what the end product will be like.

If you want to be sure, create a Text object and put a script with an update function that returns the value of (FB.IsLoggedIn), assemble an Android build, run it, log into Facebook, hard-close the game, open it without explicitly logging into FB, and see what happens - chance are, the value will be set to True even if you’ve done nothing.

To reiterate, as I confirmed yesterday, there’s absolutely no need to cache, store, or save tokens inbetween sessions, or to explicitly call FB.LogInWithReadPermissions - Facebook’s SDK really does handle it all for you, just like they said they would. :slight_smile:

Thanks for the info! :slight_smile:
I understand that the log-in screen shouldbe handled automatically by the API, but that’s not what is happening.
In iOS I always see this:

I’ll try that text object tip and investigate some more… but this is starting to drive me crazy! :frowning: