There are two things you need to do in order to get it working.
The First is to ensure that the app check initialization is happening on the client. You can encapsulate the initialization in a component with the "use client" directive (I have a providers.tsx to do this sort of thing) and then further encapsulate it in a useEffect with empty dependency array to ensure it is only ran once.
Next, is to ensure that the FIREBASE_APPCHECK_DEBUG_TOKEN attribute is available on the windows namespace.
I will show my entire providers.tsx
so that you have context as to where this is being ran in the tree:
"use cleint";
// other imports...
import {
initializeAppCheck,
ReCaptchaEnterpriseProvider,
} from 'firebase/app-check'
import { app } from '@/lib/firebase'
export default function Providers({ children }: { children: React.ReactNode }) {
const userProps = useUserData()
const toastProps = useToast()
const modalProps = useModal()
// service worker initialization omitted for brevity.
useEffect(() => {
console.log('initializing app check')
// Firebase uses a global variable to check if app check is enabled in a dev environment
if (process.env.NODE_ENV !== 'production') {
Object.assign(window, {
FIREBASE_APPCHECK_DEBUG_TOKEN:
process.env.NEXT_PUBLIC_APP_CHECK_DEBUG_TOKEN,
})
}
// NOTE* app is my Firebase APP instance, which I've imported
initializeAppCheck(app, {
provider: new ReCaptchaEnterpriseProvider(
process.env.NEXT_PUBLIC_RECAPTCHA_ENTERPRISE_KEY as string
),
isTokenAutoRefreshEnabled: true,
})
}, [])
return (
<UserContext.Provider value={userProps}>
<Analytics />
<ModalContext.Provider value={modalProps}>
<ToastContext.Provider value={toastProps}>
{children}
<ToastContainer />
</ToastContext.Provider>
</ModalContext.Provider>
<Modal
open={modalProps.showModal}
setOpen={modalProps.setShowModal}
preventOutsideClick={modalProps.preventOutsideClick}
>
{modalProps.modalChildren}
</Modal>
<div id="recaptcha-container"></div>
</UserContext.Provider>
)
}
And this is how Providers
is being used in the Root Layout
:
export default function Rootlayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html
lang="en"
>
<body>
<Providers>
<Header />
<main>{children}</main>
<Footer />
</Providers>
</body>
</html>
)
}