Hi there
I’m trying to implement Sign in with apple in flutter using the auth0 flutter library and the sign_in_with_apple package. I’ve successfully obtained an authorizationCode and exchanged it to auth0 tokens (access, id and refresh) as well as a UserProfile.
All that is left is to create a Credentials object and store it using the CredentialsManager exposed by the auth0 flutter api. I can create the object just fine, but when I try to save with with storeCredentials
, I’m met by an error:
CredentialsManagerException (SWIFT_REQUIRED_ARGUMENT_MISSING: The required argument 'credentials' is missing or has the wrong type.)
I feel like I’ve hit a wall here, and would greatly appreciate any help you might have
Thanks in advance!
No one who have implemented native login with apple in flutter?
1 Like
tyf
August 24, 2023, 9:51pm
3
Hey there @Lasse-Fisker sorry for the delayed response on this one!
I’m unfortunately not sure what the issue could be regarding the exception, but have you by any chance attempted to enable native sign in with Apple via application settings in Auth0 ?
Keep us posted!
hi @tyf thanks for replying, no worries about the delay
native sign in with apple is enabled yes. The strange thing is that I can successfully obtain a valid access token using the apple sign in and auth0 token exchange (tested this against my auth0 protected api). The error happens when trying to save the credentials locally on the native device using the auth0 flutter package.
Maybe the question would be better suited for an auth0 flutter github issue?
1 Like
tyf
August 25, 2023, 7:35pm
6
Hey @Lasse-Fisker thanks for clarifying!
Yes, I recommend opening up a GH issue agains the SDK itself - That is odd that you can get the token(s) but not save
1 Like
Super, I will open an issue on the repo. Thanks for the confirmation that it should work, It’s probably some edge case quirk.
1 Like
erdzan
September 5, 2023, 10:51am
8
Hi, I have the same issue, were you able to solve the issue or to create a github issue?
erdzan
September 5, 2023, 12:23pm
9
I created an issue here describing a fix
opened 12:18PM - 05 Sep 23 UTC
### Checklist
- [X] The issue can be reproduced in the [auth0_flutter sample … app](https://github.com/auth0-samples/auth0-flutter-samples/tree/main/sample) (or N/A).
- [X] I have looked into the [Readme](https://github.com/auth0/auth0-flutter/tree/main/auth0_flutter#readme), [Examples](https://github.com/auth0/auth0-flutter/blob/main/auth0_flutter/EXAMPLES.md), and [FAQ](https://github.com/auth0/auth0-flutter/blob/main/auth0_flutter/FAQ.md) and have not found a suitable solution or answer.
- [X] I have looked into the [API documentation](https://pub.dev/documentation/auth0_flutter/latest/) and have not found a suitable solution or answer.
- [X] I have searched the [issues](https://github.com/auth0/auth0-flutter/issues) and have not found a suitable solution or answer.
- [X] I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer.
- [X] I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).
### Description
It looks like the [CredentialsManagerSaveMethodHandler](https://github.com/auth0/auth0-flutter/blob/main/auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerSaveMethodHandler.swift) has a bug when trying to decode the Credentials class from the input in here https://github.com/auth0/auth0-flutter/blob/main/auth0_flutter/ios/Classes/CredentialsManager/CredentialsManagerSaveMethodHandler.swift#L13C23-L13C23
It always throws this error:
```
CredentialsManagerException (SWIFT_REQUIRED_ARGUMENT_MISSING: The required argument 'credentials' is missing or has the wrong type.)
```
When updating the class to:
```
import Flutter
import Auth0
struct CredentialsManagerSaveMethodHandler: MethodHandler {
enum Argument: String {
case credentials
}
let credentialsManager: CredentialsManager
func handle(with arguments: [String: Any], callback: @escaping FlutterResult) {
do {
let credentialsDictionary = arguments[Argument.credentials] as? [String: Any]
let jsonData = try JSONSerialization.data(withJSONObject: credentialsDictionary, options: [])
let credentials = try JSONDecoder().decode(Credentials.self, from: jsonData)
callback(self.credentialsManager.store(credentials: credentials))
} catch {
print("Error decoding credentials: \(error)")
callback(FlutterError(from: .requiredArgumentMissing("Failed to decode credentials: \(error.localizedDescription)")))
}
}
}
```
It seems to work.
Here is how in the Pod (Auth0) the Credentials are decoded:
```
extension Credentials: Codable {
enum CodingKeys: String, CodingKey {
case accessToken = "access_token"
case tokenType = "token_type"
case expiresIn = "expires_in"
case refreshToken = "refresh_token"
case idToken = "id_token"
case scope
case recoveryCode = "recovery_code"
}
/// `Decodable` initializer.
public convenience init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let accessToken = try values.decodeIfPresent(String.self, forKey: .accessToken)
let tokenType = try values.decodeIfPresent(String.self, forKey: .tokenType)
let idToken = try values.decodeIfPresent(String.self, forKey: .idToken)
let refreshToken = try values.decodeIfPresent(String.self, forKey: .refreshToken)
let scope = try values.decodeIfPresent(String.self, forKey: .scope)
let recoveryCode = try values.decodeIfPresent(String.self, forKey: .recoveryCode)
var expiresIn: Date?
if let string = try? values.decode(String.self, forKey: .expiresIn), let double = Double(string) {
expiresIn = Date(timeIntervalSinceNow: double)
} else if let double = try? values.decode(Double.self, forKey: .expiresIn) {
expiresIn = Date(timeIntervalSinceNow: double)
} else if let date = try? values.decode(Date.self, forKey: .expiresIn) {
expiresIn = date
}
self.init(accessToken: accessToken ?? "",
tokenType: tokenType ?? "",
idToken: idToken ?? "",
refreshToken: refreshToken,
expiresIn: expiresIn ?? Date(),
scope: scope,
recoveryCode: recoveryCode)
}
}
```
Additionally, we pass in `expiredAt`, even though `expiredIn` is required, is this intended?
Here is also another user stating the same issue: https://community.auth0.com/t/flutter-native-apple-sign-in-using-custom-ui/114027
### Reproduction
Try to save some Credentials with the default credentialsManager like this:
```
var creds = Credentials(
accessToken: accessToken,
tokenType: 'Bearer',
idToken: idToken,
refreshToken: null,
expiresAt: DateTime.now().add(Duration(
seconds:
100)),
scopes: {},
user: UserProfile(sub: sub!));
await sl<Auth0>().credentialsManager.storeCredentials(creds);
```
### Additional context
_No response_
### auth0_flutter version
1.2.1
### Flutter version
3.13.2
### Platform
iOS
### Platform version(s)
_No response_
system
Closed
September 19, 2023, 12:24pm
10
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.