Skip to content

Instantly share code, notes, and snippets.

@calderaro
Last active May 19, 2020 00:59
Show Gist options
  • Save calderaro/66b9e1a8372e51c4b00f36f9ad82fa5c to your computer and use it in GitHub Desktop.
Save calderaro/66b9e1a8372e51c4b00f36f9ad82fa5c to your computer and use it in GitHub Desktop.
Firebase-React AuthContext
import React from "react";
import { User } from "@firebase/auth-types";
import { getAuth } from "./firebase";
import { isAdmin } from "../services/auth";
export interface AuthContextState {
status: "loading" | "loaded" | "failure";
user: User | null;
isAdmin: boolean;
}
export interface AuthContextComponentProps {
authContext: AuthContextState;
}
export const AuthContext = React.createContext<AuthContextState>({
status: "loading",
user: null,
isAdmin: false,
});
export class AuthProvider extends React.Component<{}, AuthContextState> {
unsub: (() => void) | undefined = () => null;
constructor(props: {}) {
super(props);
this.state = {
status: "loading",
user: null,
isAdmin: false,
};
}
componentDidMount() {
this.unsub?.();
this.unsub = getAuth().onAuthStateChanged(this.load);
}
load = async (user: User | null) => {
if (user) {
const admin = await isAdmin();
this.setState({ status: "loaded", user, isAdmin: admin });
} else {
this.setState({ status: "loaded", user, isAdmin: false });
}
};
componentWillUnmount = () => {
this.unsub?.();
};
render() {
return (
<AuthContext.Provider value={this.state}>
{this.props.children}
</AuthContext.Provider>
);
}
}
export function WithAuth(Wrapped: React.ComponentType<any>) {
return function AuthContextWrapper(props: any) {
return (
<AuthContext.Consumer>
{(value) => <Wrapped authContext={value} {...props} />}
</AuthContext.Consumer>
);
};
}
import React from "react";
import { Redirect } from "react-router-dom";
import { AuthContext } from "../../utils/AuthContext";
export default function AuthHoc(Wrapped: React.ComponentType<any>) {
return function AuthHocWrapper(props: any) {
return (
<AuthContext.Consumer>
{(value) => {
if (value.status === "loading") {
return null;
}
if (!value.user) {
return <Redirect from="*" to="/auth/login" />;
}
return <Wrapped authContext={value} {...props} />;
}}
</AuthContext.Consumer>
);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment