Supabase/ui <Auth> component

Hi all. I was hoping to use this premade Auth component from supabase/ui in order to skip reinventing the wheel on various login/signup/password change/etc forms.
However, after successful authentication, redwood auth is naturally unaware of this and thus currentUser remains null. Is there a way to refresh redwood auth (and trigger all the appropriate component re-rendering) without having to call location.reload()?

I’m using it the following way. Thank you for any input you may have.

//App.tsx
...
const supabaseClient = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_KEY
)
const App = () => (
  <FatalErrorBoundary page={FatalErrorPage}>
    <RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
      <AuthProvider client={supabaseClient} type="supabase">
          <RedwoodApolloProvider>
            <Routes />
          </RedwoodApolloProvider>
      </AuthProvider>
    </RedwoodProvider>
  </FatalErrorBoundary>
)


//SigninPage.tsx
...
const { client, currentUser } = useAuth()

return (
<Auth supabaseClient={client} providers={['google', 'github']} />
)

Hey @tvo you might be able to something like this to refresh the authentication state.

  const { client: supabaseClient, reauthenticate } = useAuth()

  useEffect(() => {
    const { data: authListener } = supabaseClient.auth.onAuthStateChange((event) => {
     // you can look at the event here to determine if you should run it
     // for example if (event === 'PASSWORD_RECOVERY')
      await reauthenticate()
    })

    return () => {
      authListener.unsubscribe()
    }
  }, [])

you can find the list of events you can listen to here
https://supabase.com/docs/reference/javascript/auth-onauthstatechange

Thank you so much, @KrisCoulson! reauthenticate is exactly what I needed.

Below is the complete code for the wrapped component if others find themselves here with the same issue.

import { ComponentProps, useEffect } from 'react'
import { Auth } from '@supabase/ui'
import { useAuth } from '@redwoodjs/auth'
import { navigate } from '@redwoodjs/router'

interface Props extends Omit<ComponentProps<typeof Auth>, 'supabaseClient'> {}


const SupabaseAuth = (props: Props) => {
  //
  // Wrap @supabase/ui Auth component to relay SIGNED_IN event to Redwood Auth.
  // Without this, Redwood Auth's `useAuth` hook does not know we're logged in.
  //
  const { client, reauthenticate } = useAuth()

  // The <Auth> component's `redirectTo` feature doesn't naturally just work. This
  // workaround extracts that property and do the navigation ourselves.
  const { redirectTo, ...authProps } = props

  useEffect(() => {
    if (client.auth) {
      const { data: authListener } = client.auth.onAuthStateChange(
        async (event) => {
          if (event === 'SIGNED_IN') {
            await reauthenticate()
            navigate(redirectTo)
          }
        }
      )

      return () => {
        authListener.unsubscribe()
      }
    }

    //eslint-disable-next-line react-hooks/exhaustive-deps
  }, [client.auth])

  return <Auth supabaseClient={client} {...authProps}></Auth>
}

export default SupabaseAuth

1 Like