Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example useAuth hook using Zustand, SWR and Suspense
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
}
}
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment