diff --git a/package.json b/package.json index 3a7d9493..36eb0ec7 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "date-fns": "^2.28.0", "dompurify": "^2.3.6", "firebase": "^9.6.10", + "firebaseui": "^6.0.1", "jotai": "^1.6.4", "lodash": "^4.17.21", "lodash-es": "^4.17.21", @@ -27,7 +28,6 @@ "react-div-100vh": "^0.7.0", "react-dom": "^18.0.0", "react-error-boundary": "^3.1.4", - "react-firebaseui": "^6.0.0", "react-helmet-async": "^1.3.0", "react-router-dom": "^6.3.0", "react-scripts": "^5.0.0", diff --git a/src/components/FirebaseUi.tsx b/src/components/FirebaseUi.tsx index 9242fde8..0c3416a0 100644 --- a/src/components/FirebaseUi.tsx +++ b/src/components/FirebaseUi.tsx @@ -1,6 +1,9 @@ +import { useMemo, useEffect } from "react"; import { useAtom } from "jotai"; -import StyledFirebaseAuth from "react-firebaseui/StyledFirebaseAuth"; +import * as firebaseui from "firebaseui"; +import "firebaseui/dist/firebaseui.css"; +import { onAuthStateChanged } from "firebase/auth"; import { Props as FirebaseUiProps } from "react-firebaseui"; import { makeStyles } from "tss-react/mui"; @@ -12,6 +15,8 @@ import { firebaseAuthAtom } from "@src/sources/ProjectSourceFirebase"; import { publicSettingsAtom } from "@src/atoms/project"; import { defaultUiConfig, getSignInOptions } from "@src/config/firebaseui"; +const ELEMENT_ID = "firebaseui_container"; + const useStyles = makeStyles()((theme) => ({ root: { width: "100%", @@ -194,28 +199,6 @@ const useStyles = makeStyles()((theme) => ({ backgroundColor: theme.palette.primary.main + " !important", }, }, - - signInText: { - display: "block", - textAlign: "center", - color: theme.palette.text.secondary, - margin: theme.spacing(-1, 0, -3), - }, - - skeleton: { - width: "100%", - marginBottom: "calc(var(--spacing-contents) * -1)", - - "& > *": { - width: "100%", - height: 32, - borderRadius: theme.shape.borderRadius, - }, - - "& > * + *": { - marginTop: theme.spacing(1), - }, - }, })); export default function FirebaseUi(props: Partial) { @@ -223,37 +206,64 @@ export default function FirebaseUi(props: Partial) { const [firebaseAuth] = useAtom(firebaseAuthAtom, globalScope); const [publicSettings] = useAtom(publicSettingsAtom, globalScope); - const signInOptions = - Array.isArray(publicSettings.signInOptions) && - publicSettings.signInOptions.length > 0 - ? publicSettings.signInOptions - : ["google"]; + const signInOptions = useMemo( + () => + Array.isArray(publicSettings.signInOptions) && + publicSettings.signInOptions.length > 0 + ? publicSettings.signInOptions + : ["google"], + [publicSettings.signInOptions] + ); - const uiConfig: firebaseui.auth.Config = { - ...defaultUiConfig, - ...props.uiConfig, - callbacks: { - uiShown: () => { - const node = document.getElementById("rowy-firebaseui-skeleton"); - if (node) node.style.display = "none"; - }, - ...props.uiConfig?.callbacks, - }, - signInOptions: getSignInOptions(signInOptions), - }; + const uiConfig: firebaseui.auth.Config = useMemo( + () => ({ + ...defaultUiConfig, + ...props.uiConfig, + signInOptions: getSignInOptions(signInOptions), + }), + [props.uiConfig, signInOptions] + ); + + useEffect(() => { + let firebaseUiWidget: firebaseui.auth.AuthUI; + let userSignedIn = false; + let unregisterAuthObserver: ReturnType; + + // Get or Create a firebaseUI instance. + firebaseUiWidget = + firebaseui.auth.AuthUI.getInstance() || + new firebaseui.auth.AuthUI(firebaseAuth); + + if (uiConfig.signInFlow === "popup") firebaseUiWidget.reset(); + + // We track the auth state to reset firebaseUi if the user signs out. + unregisterAuthObserver = onAuthStateChanged(firebaseAuth, (user) => { + if (!user && userSignedIn) firebaseUiWidget.reset(); + userSignedIn = !!user; + }); + + // Render the firebaseUi Widget. + firebaseUiWidget.start("#" + ELEMENT_ID, uiConfig); + + return () => { + unregisterAuthObserver(); + firebaseUiWidget.reset(); + }; + }, [firebaseAuth, uiConfig]); return ( <> - + Continue with - +
); } diff --git a/src/index.tsx b/src/index.tsx index 79f1b471..1431d56f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -20,25 +20,25 @@ export const muiCache = createCache({ key: "mui", prepend: true }); const container = document.getElementById("root")!; const root = createRoot(container); root.render( - // - - - - - - - - - - - - - - - - - - // + + + + + + + + + + + + + + + + + + + ); // If you want to start measuring performance in your app, pass a function diff --git a/yarn.lock b/yarn.lock index 474822e1..8d385e58 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6307,7 +6307,7 @@ firebase@^9.6.10: "@firebase/storage-compat" "0.1.12" "@firebase/util" "1.5.1" -firebaseui@^6.0.0: +firebaseui@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/firebaseui/-/firebaseui-6.0.1.tgz#bdabc69de9c245975a1277d507b2f0ff0044e558" integrity sha512-SMNCFt/xns3mnvd0hImEDu7di5fqRU3MVyIaXpVEfg6v0bH6f3m+YybivU7KElRUT/47DHMn++D8MrZYYnoN5g== @@ -9502,13 +9502,6 @@ react-fast-compare@^3.2.0: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== -react-firebaseui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/react-firebaseui/-/react-firebaseui-6.0.0.tgz#97a075e7caa2fb969c8ded9efbbcefccb1f33ce1" - integrity sha512-VzLMiW7DBZCsW/qpP9nky/pPlAoIjDxA2Qyc+QAPf+RjelIkvPPiCBXR2aAz+Upy+ujrx6pYDXj547DW5uC4ww== - dependencies: - firebaseui "^6.0.0" - react-helmet-async@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.3.0.tgz#7bd5bf8c5c69ea9f02f6083f14ce33ef545c222e"