ウェブサイト検索

TypeScript - NextJSのgetServerSidePropsで初期化前の変数にアクセスできません


私は Firebase を使って作業しており、firebase.tsx で必要なデータを取得するための API と関数を初期化し、その後 pages/index.tsx ファイルでそれらをインポートしていますが、Firebase アプリの初期化後にエクスポートにアクセスできません

services/firebase.tsx:

import firebase, { FirebaseOptions } from 'firebase/app'
import { getAuth } from 'firebase/auth';
import { collection, doc, setDoc, getFirestore, query, where, getDocs, orderBy } from "firebase/firestore";
import { getStorage } from 'firebase/storage';
import { getAnalytics } from "firebase/analytics";

import config from '../config';

import Blog, { blogConverter } from "../models/Blog";

export const yo = 'yo'

if (!firebase.getApps().length) {
    firebase.initializeApp(config.firebaseConfig as FirebaseOptions);
}

export const auth = getAuth();
export const firestore = getFirestore();
export const storage = getStorage();
export const analytics = getAnalytics();

/**
 * Get all blogs from firebase
 * @returns {Promise<Blog[]>} A promise that resolves to an array of Blog objects
 */
export const getBlogs = async (): Promise<Blog[]> => {
    const q = query(
        collection(firestore, "blogs"),
        where("status", "==", "published"),
        where("publish_date", "<", new Date().toUTCString()),
        orderBy("publish_date", "desc")
    ).withConverter(blogConverter);

    const querySnapshot = await getDocs(q);
    if (querySnapshot.empty) return [];

    const allBlogs: Blog[] = querySnapshot.docs.map(doc => doc.data());
    return allBlogs;
}

ページ/インデックス.tsx

import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import { GetServerSideProps } from 'next'
import { getBlogs, yo } from '../services/firebase'

import Link from 'next/link'

import Blog from '../models/Blog'

export const getServerSideProps: GetServerSideProps = async (context) => {
  console.log(yo)

  const blogs = await getBlogs()
  return {
    props: {
      blogs
    }
  }
}

interface Props {
  blogs: Blog[]
}

const Home: NextPage<Props> = ({ blogs }) => {
...
}

15行目の後にexport const yo='yo'を移動すると、「初期化前に 'yo' にアクセスできません」というエラーが出ますが、現在の場所にある場合は出ません。

Firebase の初期化がエクスポートの初期化を遅らせるように見えますが、他の人が同じパターンを使っているのを見たことがありますか?

何が足りないのですか?

エラーメッセージ

回答 #1

Firebase JavaScript SDK(≥ v9.0)は新しいモジュラーAPIを導入しており、破壊的変更が含まれています。もしv8を使用している場合は、バージョン9.0.0以降でも動作させるためにコードを更新する必要があります。バージョン9 SDKの大部分はバージョン8と同じパターンに従っていますが、コードの構成は異なります。ですので、バージョン9のインポートでの問題はバグではなく、インポート方法の新しい形だということです。

例えば、バージョン8のドットチェーン(firebaseApp.auth()など)は、バージョン9ではfirebaseAppを受け取り、Authenticationインスタンスを返す単一のgetAuth()関数に置き換えられます。これは、バージョン8以前で作成されたWebアプリが、バージョン9のモジュール方式を利用するためにはリファクタリングが必要であることを意味します。Firebaseは、v9への移行を容易にする互換ライブラリを提供しています。おっしゃる通り、インポートを更新する必要があります。

から

前:バージョン8

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

〜へ

以降:バージョン9互換

// v9 compat packages are API compatible with v8 code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
 

また、コードをモジュラースタイルに応じてリファクタリングすることもできますが、これは互換バージョンとは少し異なります。これらすべてはここに文書化されています。違いを明確に理解するために確認してみてください。

回答 #2

また、こちらに記載されている以下の点についてご注意ください。

覚えておいてください: compatライブラリは一時的な解決策であり、将来の主要なSDKバージョン(例えばバージョン10やバージョン11)で完全に削除される予定です。最終的な目標は、compatコードを削除し、アプリにはバージョン9のモジュール式コードのみを残すことです。

つまり、「compat」は、あまり手を加えずにv8のコードをv9で動作させるための一時的な解決策にすぎません。最終的には、コードをモジュール式のスタイルにリファクタリングする必要があります。