skip to Main Content

I use FirebaseAuthUi to manage authentication in my app.

When users are logged in, I need their Facebook access token to make a graph request. It works fine the first time users log in, but when the app is re-launched the graph API call doesn’t work because I don’t have the Facebook access token anymore.

So I need to save this token in UserDefaults or Keychain. My issue is that I don’t manage to save this token as an AccessToken. I can save it as a String, but then when I want to make my graph call I need an AccessToken and I think that I cannot get an AccessToken from the String saved.

Do you see how I could make it ? Here is my code :

//checkLoggedIn
authHandle = Auth.auth().addStateDidChangeListener { auth, user in
    if let user = user {
        // User is signed in.

        UserDefaults.standard.set(String(describing: AccessToken.current), forKey: "savedFacebookToken")
        UserDefaults.standard.synchronize()
        let savedFacebookToken = UserDefaults.standard.object(forKey: "savedFacebookToken")

        let connection = GraphRequestConnection()
        connection.add(GraphRequest(graphPath: "/me/friends", accessToken: savedFacebookToken as! AccessToken)) { httpResponse, result in

I get the following error message :

Could not cast value of type 'Swift._NSContiguousString' (0x10a0f4f50) to 'FacebookCore.AccessToken' (0x1068aa9f0).

Edit :
I haven’t been able to test it on a real device yet.

3

Answers


  1. Your access token is integer it is not type casting in string. you can save value as this or according your save value you can use last line code.

     UserDefaults.standard.set(AccessToken.current, forKey: "savedFacebookToken")
    

    Get token value

    let currenttoken  = UserDefaults.standard.integer(forKey: "savedFacebookToken")
    

    or you can typecast into string

     let currenttoken=  UserDefaults.standard.object(forKey: "savedFacebookToken") as! String
    
    Login or Signup to reply.
  2. FacebookCore.AccessToken is a struct, which means you can’t save it directly to UserDefaults but you need it to create graph request.

    enter image description here

    It means the SDK must provide you access token value for cases where user has already logged in. There is a method in AccessToken class which gives you exactly that

    enter image description here

    You just need to refresh current Token and extend the token’s expiration.

    AccessToken.refreshCurrentToken { accessToken, error in
        if let currentAccessToken = accessToken {
            let connection = GraphRequestConnection()
            connection.add(GraphRequest(graphPath: "/me/friends", accessToken: currentAccessToken)) {..}
        } else {
            // Show Login
        }
    }
    
    Login or Signup to reply.
  3. More better way of doing this-:

    Create extension for userDefaults-:

    import  Foundation
    // EXTENSION TO USER DEFAULTS
    extension UserDefaults{
    
        // CREATE ENUM HAVING 1 STATE VALUE
    
        enum userDefaultKeys:String {
            case FacebookToken
           }
    
        // SAVE ACCESS TOKEN IN USER DEFAULTS
    
        func setAccessToken(id:String){
            set(id, forKey: userDefaultKeys.FacebookToken.rawValue)
            synchronize()
        }
    
    // GET ACCESS TOKEN FROM USER DEFAULTS
    
        func getAccessToken()->String{
    
            return string(forKey: userDefaultKeys.FacebookToken.rawValue)
        }
    }
    

    In your controller class just call methods like -:

    To set -:

    // SET TOKEN AS STRING TO USER DEFAULTS
    
    UserDefaults.standard.setAccessToken(value: "token") 
    

    To get-:

    // GET TOKEN RESULT AS STRING
    
        fileprivate func getSavedFacebookToken() -> String{
            return UserDefaults.standard.getAccessToken()
        }
    

    According to your code-:

    //checkLoggedIn
    authHandle = Auth.auth().addStateDidChangeListener { auth, user in
        if let user = user {
            // User is signed in.
    
            UserDefaults.standard.setAccessToken(id: String(describing: AccessToken.current))
            let savedFacebookToken = UserDefaults.standard.getSavedFacebookToken()
    
             let connection = GraphRequestConnection()
            connection.add(GraphRequest(graphPath: "/me/friends", accessToken: AccessToken(savedFacebookToken))) { httpResponse, result in
    

    REAMRK-:

    Never save Access Token in UserDefaults . NSUserDefaults is easily
    readable even on a non-jailbroken device. If security is a concern to
    you, then I would store the data in the Keychain.

    Please refer below link-:

    Storing authentication tokens on iOS – NSUserDefaults vs Keychain?

    And i would say no need to save token it can expire or change which can create issues in your app.

    Read Facebook document regarding Access Token for more clarification-:

    https://developers.facebook.com/docs/facebook-login/access-tokens

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search