So I follow this example https://backstage.forgerock.com/docs/sdks/latest/sdks/integrations/build-protected-reactnative-mobile-app-part-one.html and all works fine without any issue. Problem is whenever app is killed or reloaded when try to call native method to get access token get error that user does not exists. Per docs if native sdk is not initialized it could throw this error. Not sure what we are missing in order to get access token.
Whenever i call
@objc func getAccessToken(
_ resolve: @escaping RCTPromiseResolveBlock,
rejecter reject: @escaping RCTPromiseRejectBlock) {
guard let user = FRUser.currentUser else {
/**
* If no currently authenticated user is found, log error.
*/
let errorMsg = "Invalid SDK state: No current user for which to request access tokens"
FRLog.e(errorMsg)
reject("error", errorMsg, nil)
return
}
user.getAccessToken { user, error in
if let error = error {
FRLog.e(String(describing: error))
reject("error", error.localizedDescription, error)
}
else if let user = user, let accessToken = user.token {
let encoder = JSONEncoder()
do {
let data = try encoder.encode(accessToken)
let string = String(data: data, encoding: .utf8)
FRLog.i(string ?? "Encoding of token failed")
resolve(string)
} catch {
reject("Error", "Serialization of tokens failed", error)
}
}
else {
let errorMsg = "Invalid SDK state: getAccessToken returned no result"
FRLog.e(errorMsg)
reject("error", errorMsg, nil)
}
}
}
I should be able to get token
// MARK: - AccessToken
/// Retrieves access_token from Keychain storage, and if current access_token is expired, then consumes refresh_token to refresh access_token, and returns FRUser with newly granted access_token
///
/// - Parameter completion: Completion block which returns newly refreshed FRUser object
@objc
public func getAccessToken(completion:@escaping UserCallback) {
if let frAuth = FRAuth.shared, let tokenManager = frAuth.tokenManager {
tokenManager.getAccessToken { (token, error) in
if let token = token {
self.token = token
self.save()
completion(self, nil)
}
else {
completion(nil, error)
}
}
}
else {
FRLog.w("Invalid SDK state; missing TokenManager")
completion(nil, ConfigError.invalidSDKState)
}
}
But before i call this method i need to call get user.
/**
Singleton instance represents currently authenticated user.
## Note ##
If SDK has not been started using *FRAuth.start()*, *FRUser.currentUser* returns nil even if user session has previously authenticated, and valid.
*FRUser.currentUser* would only returns an object when there is either or both of following:
- Session Token authenticated by AM's Authentication Tree
- OAuth2 token set issued by previously authenticated Session Token
*/
@objc
public static var currentUser: FRUser? {
get {
if let staticUser = _staticUser {
return staticUser
}
else if let frAuth = FRAuth.shared {
FRLog.v("FRUser retrieved from SessionManager")
if let accessToken = try? frAuth.keychainManager.getAccessToken() {
_staticUser = FRUser(token: accessToken)
}
else if let _ = frAuth.keychainManager.getSSOToken() {
_staticUser = FRUser(token: nil)
}
return _staticUser
}
FRLog.w("Invalid SDK State: FRUser is returning 'nil'.")
return nil
}
}
And i get error
let errorMsg = "Invalid SDK state: No current user for which to request access tokens"