Closed baptiste-veyrard closed 2 weeks ago
Just leaving some info from the Flutter side here:
The supabase-flutter SDK stores the session in the following format.
{
"access_token": accessToken,
"expires_in": expiresIn,
"expires_at": expiresAt,
"refresh_token": refreshToken,
"token_type": tokenType,
"provider_token": providerToken,
"provider_refresh_token": providerRefreshToken,
"user": {<user json>},
}
supabase-flutter does allow developers to store the token in any location they want by defining a custom local storage, so as long as the shape of the session json match, sharing session between the Flutter and Swift SDK should be possible, but does the shape of the JSON structure match @grdsdev ?
Thanks for your answer. Indeed, I use a custom local storage, in the keychain via flutter_secure_storage. I well retrieve the data stored in it from my swift code, but it cannot be retrieved as a supabase session given the differences of the JSON values stored.
The JSON structures I provided in my post are the actual structures I retrieve when I print a session created in Swift and Flutter.
The format you provided is the session itself, in JSON, but when stored, it uses the following piece of code in session.dart (file of the supabase flutter package).
String get persistSessionString { final data = {'currentSession': toJson(), 'expiresAt': expiresAt}; return json.encode(data); }
And the Supabase Swift package is looking for the keyword "currentSession" and not "session". I succeed to make them matching in modifying the flutter sdk just for testing purpose, but modifying it is not a proper way to handle it for a long term perspective for a production app.
That is why then I tried to make my own JSON Decoder, but while well initialized, the supabase swift package does not use it to decode the retrieve session in the keychain unfortunatelly.
One workaround would be to modify the "data" value in a function before storing it via my custom local storage function, so without changing the package, but I thought it was a better idea to talk about it with the Supabase team first.
Hi @dshukertjr
Session JSON structure is compatible with Flutter, as it uses the same structure, the issue I see is that Flutter stores it in a currentSession
key, along with a expiresAt
. Swift uses the same approach, but stores in under a session
key, and expirationDate
, that is where the incompatibility happens.
If we match only those 2 keys, all should work as expected, without the need of custom decoding on Swift.
@baptiste-veyrard the reason for this not using your own JSON Decoder for decoding the session, is because I didn't want to expose the decoding/encoding of the internal stored session, and let you customize the storing/retrieving of raw Data
through the custom local storage only.
@dshukertjr which one you prefer? (I prefer 2, as there is not need for the wrapping keys anymore)
@baptiste-veyrard
The format you provided is the session itself, in JSON, but when stored, it uses the following piece of code in session.dart (file of the supabase flutter package).
That was the behavior of the v1 package, and it is no longer the behavior in the latest versions. Latest versions store the sessions in the format that I outlined up here. Please use the latest versions to verify the most up-to-date behavior.
Bug report
Description:
I'm developing an application where I need to share a Supabase session between my main app, built using FlutterFlow (which uses the Supabase Flutter SDK), and an iOS extension target (a credential provider) where auth is built using the Supabase Swift SDK. I've encountered an issue where the session JSON structure used by the Supabase Flutter SDK is incompatible with what is expected by the Supabase Swift SDK. So it makes the JSON stored by the flutter SDK not parseable by the swift SDK.
JSON Structures:
Supabase Swift SDK
{ "session": { "expires_in": 3290.1477999687195, "expires_at": 1724170095, "refresh_token": "6hgVKxl.......", "access_token": "eyJhbGciOiJIUzI1NiIsImtpZCI6ImwzY0JFV1dJZjBMQjZYTk0iLCJ0eXAiOiJKV1QifQ...", "user": { "email": "email@digdy.com", "user_metadata": { "sub": "7e852d69-XXXX-XXXX-XXXX-42b02d8edc85", "phone_verified": false, "email": "email@digdy.com", "email_verified": false }, ... }, "token_type": "bearer" }, "expiration_date": "2024-08-20T16:08:15.000Z" }
Supabase Flutter SDK
{ "currentSession": { "access_token": "eyJhbGciOiJIUzI1NiIsImtpZCI6ImwzY0JFV1dJZjBMQjZYTk0iLCJ0eXAiOiJKV1QifQ...", "expires_in": 3600, "refresh_token": "6hgVKxl_Bkt537lJDCQkrw", "token_type": "bearer", "user": { "id": "7e852d69-e353-4852-8891-42b02d8edc85", "app_metadata": { "provider": "email", "providers": ["email"] }, ... } }, "expiresAt": 1724170095 }
To Reproduce
Steps to reproduce the behavior, please provide code snippets or a repository:
Expected behavior
The Supabase SDKs for both Flutter and Swift should use a compatible JSON structure for session management, allowing seamless sharing of sessions between different platforms. Due to the print in the CredentialProviderViewController (in viewDidLoad) it should return a valid session.
Actual Behavior: The session JSON structure used by the Supabase Flutter SDK is incompatible with the structure expected by the Supabase Swift SDK, leading to decoding errors and the inability to share sessions across these platforms. The function init() in SupabaseAuthManager.swift return the following error:
Failed to load session: keyNotFound(CodingKeys(stringValue: "session", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"session\", intValue: nil) (\"session\").", underlyingError: nil))
System information
More info: I cloned a swift package in order to add some prints in the package code to identify where the issue happened. It seems to happen in the "SessionStorage" file, at the line of code:
return try storedData.flatMap { try AuthClient.Configuration.jsonDecoder.decode(StoredSession.self, from: $0).session }
As well, I tried to set my own JSONDecoder as it seems to be possible through the auth option of the supabase client. It was well initialized, but the SDK still uses the "original" JSONDecoder to perform the decoding tasks.