Skip to content

Conversation

@grdsdev
Copy link
Contributor

@grdsdev grdsdev commented Oct 13, 2025

What kind of change does this PR introduce?

Bug fix

What is the current behavior?

  1. Customer reads the currentSession variable which returns the stored session, without validating if it is expired or not, and lets users in.
  2. Then the customer attaches an authStateChange listener and receives initialSession = nil, since the stored session couldn't be refreshed.
  3. The user has been logged in but now has no session, making all API calls fail.

Although the behavior above isn't wrong nor a bug, since it is documented that the currentSession may have been expired, it is a behavior that just brings more confusion to the usage.

What is the new behavior?

Added a new trait EmitLocalSessionAsInitialSession for customers to opt-in to the new behavior since this is a breaking change.

supabase.auth.onAuthStateChanges { event, session in 
    if event == .initialSession {
        if let session {
            if session.isExpired {
                // Session exists but has been expired. It will try to refresh it in the background and emit a `tokenRefresh` or `signOut` event depending on the result.
                // Probably should show a loading indicator until a `tokenRefreshed`/`signOut` event is received.
            } else {
                // Session exists and is valid, can let user in.
            }
        } else {
            // Session does not exist, user needs to sign in
        }
    } else if event == .tokenRefreshed {
        assert(session != nil && session?.isExpired == false)
    } else if event == .signOut {
        assert(session == nil)
    }
}

Additional context

#630
#753

@coveralls
Copy link

coveralls commented Oct 13, 2025

Pull Request Test Coverage Report for Build 18477966756

Details

  • 14 of 14 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.2%) to 77.582%

Totals Coverage Status
Change from base Build 18462418370: 0.2%
Covered Lines: 5942
Relevant Lines: 7659

💛 - Coveralls

@grdsdev grdsdev merged commit c5721fe into main Oct 15, 2025
23 checks passed
@grdsdev grdsdev deleted the guilherme/ghost-initial-session branch October 15, 2025 09:51
@vojtabohm
Copy link

vojtabohm commented Oct 31, 2025

Hello @grdsdev. I just realised, there is no way to enable the trait in Xcode, as iOS projects are not pure SPM projects. There is no Package.swift where you could just enable it and there is no UI or command-line support to enable this feature.

Also, upon reading Apple's docs regarding traits:

Traits must be strictly additive and enabling a trait must not remove API.

In this case, the trait removes/alters API behavior, which might not align with that rule.

Do you think we could come up with a different solution? Runtime flags instead? Compilation flag? A new authStateChanges property?

Apologies for not raising this before it got to production. I didn't give much thoughts to Traits as I just now familiarised with them.

@grdsdev
Copy link
Contributor Author

grdsdev commented Nov 3, 2025

Thanks @vojtabohm for bringing that up. You're right, we're not using traits as it is supposed to be used.

I decided to add a runtime flag when initializing the client, you can follow it on #844

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

5 participants