Factor out FirebaseAppContext.
rodzic
bec2c4eb49
commit
3fc6a699a0
42
lib/auth.tsx
42
lib/auth.tsx
|
@ -8,7 +8,7 @@ import {
|
||||||
Auth,
|
Auth,
|
||||||
User,
|
User,
|
||||||
} from "firebase/auth";
|
} from "firebase/auth";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useContext, useEffect, useState } from "react";
|
||||||
|
|
||||||
const DEFAULT_APP_CONFIG: FirebaseOptions = {
|
const DEFAULT_APP_CONFIG: FirebaseOptions = {
|
||||||
apiKey: "AIzaSyAV1kkVvSKEicEa8rLke9o_BxYBu1rb8kw",
|
apiKey: "AIzaSyAV1kkVvSKEicEa8rLke9o_BxYBu1rb8kw",
|
||||||
|
@ -51,20 +51,40 @@ export interface AuthContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
type FirebaseGithubAuthState = {
|
type FirebaseGithubAuthState = {
|
||||||
app: FirebaseApp;
|
|
||||||
auth: Auth;
|
auth: Auth;
|
||||||
provider: GithubAuthProvider;
|
provider: GithubAuthProvider;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const FirebaseAppContext = React.createContext<FirebaseApp | null>(null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Firebase GitHub authentication provider.
|
* A Firebase app provider. Any other components that use Firebase must
|
||||||
|
* be a child of this.
|
||||||
*
|
*
|
||||||
* Note this component is assumed to never be unmounted, nor
|
* Note this component is assumed to never be unmounted, nor
|
||||||
* for its props to change.
|
* for its non-children props to change.
|
||||||
*/
|
*/
|
||||||
export const FirebaseGithubAuthProvider: React.FC<{
|
export const FirebaseAppProvider: React.FC<{ config?: FirebaseOptions }> = ({
|
||||||
config?: FirebaseOptions;
|
config,
|
||||||
}> = ({ config, children }) => {
|
children,
|
||||||
|
}) => {
|
||||||
|
const [app, setApp] = useState<FirebaseApp | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setApp(initializeApp(config || DEFAULT_APP_CONFIG));
|
||||||
|
}, [config]);
|
||||||
|
|
||||||
|
return <FirebaseAppContext.Provider value={app} children={children} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Firebase GitHub authentication provider. Must be a child of a
|
||||||
|
* `FirebaseAppProvider`.
|
||||||
|
*
|
||||||
|
* Note this component is assumed to never be unmounted.
|
||||||
|
*/
|
||||||
|
export const FirebaseGithubAuthProvider: React.FC<{}> = ({ children }) => {
|
||||||
|
const app = useContext(FirebaseAppContext);
|
||||||
const [state, setState] = useState<FirebaseGithubAuthState | null>(null);
|
const [state, setState] = useState<FirebaseGithubAuthState | null>(null);
|
||||||
const [user, setUser] = useState<User | null>(null);
|
const [user, setUser] = useState<User | null>(null);
|
||||||
const [error, setError] = useState<string | undefined>(undefined);
|
const [error, setError] = useState<string | undefined>(undefined);
|
||||||
|
@ -72,17 +92,17 @@ export const FirebaseGithubAuthProvider: React.FC<{
|
||||||
const handleError = (e: Error) => setError(e.message);
|
const handleError = (e: Error) => setError(e.message);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const app = initializeApp(config || DEFAULT_APP_CONFIG);
|
if (!app) return;
|
||||||
const auth = getAuth(app);
|
const auth = getAuth(app);
|
||||||
const provider = new GithubAuthProvider();
|
const provider = new GithubAuthProvider();
|
||||||
|
|
||||||
setState({ app, auth, provider });
|
setState({ auth, provider });
|
||||||
onAuthStateChanged(auth, setUser);
|
onAuthStateChanged(auth, setUser);
|
||||||
}, [config]);
|
}, [app]);
|
||||||
|
|
||||||
const context: AuthContext = {
|
const context: AuthContext = {
|
||||||
loggedInUser: user && user.displayName,
|
loggedInUser: user && user.displayName,
|
||||||
providerName: "GitHub",
|
providerName: state && "GitHub",
|
||||||
error,
|
error,
|
||||||
login: useCallback(() => {
|
login: useCallback(() => {
|
||||||
setError(undefined);
|
setError(undefined);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import { FirebaseGithubAuthProvider } from "./auth";
|
import { FirebaseAppProvider, FirebaseGithubAuthProvider } from "./auth";
|
||||||
import { PageContext, PAGE_QUERY_ARG } from "./page";
|
import { PageContext, PAGE_QUERY_ARG } from "./page";
|
||||||
import { pageNames, Pages, toPageName, DEFAULT_PAGE } from "./pages";
|
import { pageNames, Pages, toPageName, DEFAULT_PAGE } from "./pages";
|
||||||
|
|
||||||
|
@ -57,11 +57,13 @@ const App: React.FC<{}> = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<FirebaseAppProvider>
|
||||||
<FirebaseGithubAuthProvider>
|
<FirebaseGithubAuthProvider>
|
||||||
<PageContext.Provider value={ctx}>
|
<PageContext.Provider value={ctx}>
|
||||||
<PageComponent />
|
<PageComponent />
|
||||||
</PageContext.Provider>
|
</PageContext.Provider>
|
||||||
</FirebaseGithubAuthProvider>
|
</FirebaseGithubAuthProvider>
|
||||||
|
</FirebaseAppProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue