Created
July 19, 2021 04:32
-
-
Save samselikoff/ac8076c6c224786da23c9297567585cf to your computer and use it in GitHub Desktop.
Example useAuth hook using Zustand, SWR and Suspense
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import firebase from "firebase/app"; | |
import "firebase/auth"; | |
import { gql, GraphQLClient } from "graphql-request"; | |
import { SWRConfig } from "swr"; | |
import create from "zustand"; | |
import { computed } from "zustand-middleware-computed-state"; | |
const firebaseConfig = { | |
// | |
}; | |
let firebaseApp = !firebase.apps.length | |
? firebase.initializeApp(firebaseConfig) | |
: firebase.app(); | |
let auth = firebaseApp.auth(); | |
const client = new GraphQLClient( | |
"https://fitness-challenge-backend.herokuapp.com/v1/graphql", | |
{ headers: {} } | |
); | |
let firebaseUser; | |
let promise = new Promise((r) => (resolve = r)); | |
let resolve; | |
export const useStore = create( | |
computed( | |
(set, get) => ({ | |
currentUser: undefined, | |
getSessionToken: () => firebaseUser.getIdToken(), | |
login: (email, password) => | |
auth.signInWithEmailAndPassword(email, password), | |
logout: () => auth.signOut(), | |
}), | |
(state) => { | |
let status = | |
state.currentUser === undefined | |
? "unknown" | |
: state.currentUser === null | |
? "anonymous" | |
: "authenticated"; | |
return { | |
status, | |
}; | |
} | |
) | |
); | |
auth.onAuthStateChanged(async (f) => { | |
firebaseUser = f; | |
if (firebaseUser) { | |
let res = await fetcher( | |
currentUserQuery, | |
JSON.stringify({ id: firebaseUser.uid }) | |
); | |
useStore.setState({ | |
currentUser: res.users_by_pk, | |
}); | |
} else { | |
useStore.setState({ currentUser: null }); | |
} | |
resolve(); | |
}); | |
let fetcher = async (query, variables = "{}") => { | |
if (firebaseUser) { | |
let token = await firebaseUser.getIdToken(); | |
client.setHeader("authorization", token); | |
} | |
return client.request(query, JSON.parse(variables)); | |
}; | |
export default function AuthedSWRProvider({ children }) { | |
let status = useStore((state) => state.status); | |
if (status === "unknown") { | |
throw promise; | |
} | |
return <SWRConfig value={{ fetcher }}>{children}</SWRConfig>; | |
} | |
let currentUserQuery = gql` | |
query CurrentUser($id: String!) { | |
users_by_pk(id: $id) { | |
id | |
name | |
} | |
} | |
`; |
Don't have time to look into this in detail unfortunately! Your best bet is asking on a Discord server or a relevant GitHub Issues forum.
ok thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://stackblitz.com/github/vaynevayne/react-auth?file=src%2Frouters.tsx%3AL37
hello, I refer to your idea to build a template project, but there is a problem that the redirect in the rootLoader will not execute. Could you please help me see?