0

I am implementing Firebase using Typescript in Next.js15, and in order to improve the security of access to Firestore and Storage, in addition to implementing security rules, I am also enabling Firebase App Check using reCAPTCHA v3 to receive only verified requests.

The initialization of the client-side Firebase App Check for access to Firestore and Storage has been verified without any problems. Following to the Firebase documentation, I am trying to initialize the FirebaseServerApp to call SSR using the AppCheck token obtained at initialization, but I cannot initialize it at all and cannot access Firestore or Storage with SSR.

enter image description here

How can I complete the initialization of Firebase AppCheck in the Next.js SSR environment and verify requests without any problems?

/lib/firebase.ts:

import { getApps, initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";

const firebaseConfig = {
    apiKey: process.env.NEXT_PUBLIC_FIREBASE_APIKEY,
    authDomain: "xxxxxxxxxxxxxxxxxxxx.firebaseapp.com",
    projectId: "xxxxxxxxxxxxxxxxxxxx",
    storageBucket: "xxxxxxxxxxxxxxxxxxxx.firebasestorage.app",
    messagingSenderId: "0000000000",
    appId: "0:00000000000:web:00000000000000000000",
    measurementId: "G-XXXXXXXXX"
};

const app = !getApps().length ? initializeApp(firebaseConfig) : getApps()[0];

const firestore = getFirestore();
const storage = getStorage();

export { firestore, storage, app };

/firebase_initializer.tsx:

/* Initialize FirebaseAppCheck by placing it in the root layout */

'use client';

import { app } from '@/app/lib/firebase/firebase';
import { getToken } from 'firebase/app-check';
import { useEffect } from 'react';

const FirebaseInitializer = () => {
    useEffect(() => {
        const initializeAppCheckWithRetry = async () => {
            if (typeof window !== "undefined") {
                import("firebase/app-check").then(async (firebaseAppCheck) => {
                    const captachp = process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY as string;
                     const appcheck = firebaseAppCheck.initializeAppCheck(app, {
                         provider: new firebaseAppCheck.ReCaptchaV3Provider(captachp),
                         isTokenAutoRefreshEnabled: true,
                     });
      
                     getToken(appcheck, true).then((token) => {    
                         document.cookie = `firebaseAppCheck=${token}`;
                     });
                 });
             }
        };

        initializeAppCheckWithRetry();
    }, []);

    return null;
}

export default FirebaseInitializer;

blog/page.tsx:

Also, somehow, there is no property called appCheckToken in FirebaseServerAppSettings. Therefore, we are using the Any type as a temporary solution.

import { fetchBlogImageList } from '@/app/lib/actions';
import BlogDetail from '@/app/ui/blog_detail/blog_detail';
import { BlogCategory } from '@/app/utils/enum/blog_category';
import { Blog } from '@/app/utils/type/blog';
import { FirebaseServerAppSettings, initializeServerApp } from 'firebase/app';
import { doc, getDoc, getFirestore, Timestamp } from 'firebase/firestore';
import { cookies } from 'next/headers';
import React from 'react'


const Page = async({ params }: { params: Promise<{ id: string }> }) => {
    const firebaseConfig = {
        apiKey: process.env.NEXT_PUBLIC_FIREBASE_APIKEY,
        authDomain: "xxxxxxxxxxxxxxxxxxxx.firebaseapp.com",
        projectId: "xxxxxxxxxxxxxxxxxxxx",
        storageBucket: "xxxxxxxxxxxxxxxxxxxx.firebasestorage.app",
        messagingSenderId: "0000000000",
        appId: "0:00000000000:web:00000000000000000000",
        measurementId: "G-XXXXXXXXX"
    };

    const appCheckToken = (await cookies()).get("firebaseAppCheck")?.value;

    if (!appCheckToken) {
        throw new Error("App Check token is missing in SSR.");
    }

    const firebaseServerAppSettings : any = {
        appCheckToken : appCheckToken
    }

    const serverApp = initializeServerApp(firebaseConfig, firebaseServerAppSettings)

    const firestore = getFirestore(serverApp);

    const ref = doc(firestore, "blog", id);
    const docSnapshot = await getDoc(ref);

    const data = docSnapshot.data();
    const blogData : Blog = {
        blog_id : data!!.blogId,
        created_at : (data!!.createdAt as Timestamp).toMillis(),
        title : data!!.title,
        category : data!!.category as BlogCategory,
        thumbnail : data!!.thumbnail,
        messages : data!!.messages,
        youtube : data!!.youtube
    }


    const imagesList = await fetchBlogImageList(id, blogData.messages.map(message => message.images));


     return (
         <main className='w-full h-full items-center justify-items-center'>
             <BlogDetail blog={blogData} blogImages={imagesList}/>
         </main>
     )
}

export default Page;
9
  • "I cannot initialize it at all" Why not? Any error message? Commented May 24 at 20:11
  • In the official Firebase reference, the appCheckToken is passed to firebaseServerAppSettings, and then passed as an argument to the initializeServerApp method to initialize access to the SSR-only firebase. However, in reality, when the appCheckToken is passed to firebaseServerAppSettings, it is said that such a property does not exist. Even if you force it to have an appCheckToken as an any type and initialize it with the initializeServerApp method, it will not be initialized, and the request to firestore will be displayed as an unverified request and access will be denied. Commented May 25 at 1:39
  • So this part of your post is your actual concern "there is no property called appCheckToken in FirebaseServerAppSetting"? Commented May 25 at 14:21
  • No. My purpose is to finally complete the verification of requests in the Next.js SSR environment using Firebase App Check, and the issue with the FirebaseServerAppSetting property is merely a problem that arose in the process of my attempt to achieve that purpose. As long as I can achieve my purpose of verification using App Check, I don't really care about FirebaseServerAppSetting problem. Commented May 26 at 0:15
  • If you don't care about something, please remove it from your question (there's an edit link right under it) to improve the chances that someone can help. --- Back to my first comment: Why can't you complete the process? Is there any error message? If not, what isn't working? Commented May 26 at 1:27

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.