Encountering issues with accessing a variable before its initialization in the getServerSideProps function in

Currently, I am working on setting up Firebase and configuring the APIs and functions to retrieve necessary data in my firebase.tsx file. Afterwards, I import them into my pages/index.tsx file but I am encountering an issue where I cannot access exports after initializing the Firebase app

Here is a snippet from 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;
}

This is how it's being used in pages/index.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 }) => {
...
}

By moving export const yo = 'yo' after line 15, the error "cannot access 'yo' before initialization" occurs, but placing it where it currently is does not trigger any errors.

It appears that the initialization of Firebase is affecting the sequence of exports, although I've seen others use a similar approach without issues. What could I be overlooking?

Error Message https://i.sstatic.net/WsmSS.png

Answer №1

The Firebase JavaScript SDK version 9.0 introduces a new modular API with breaking changes. If your code is based on v8, you'll need to update it to work with version 9.0.0 and above. While version 9 follows similar patterns as version 8, the code organization is different. It's not an issue with version 9 imports but rather a new way of handling them.

For instance, in version 8, dot-chaining like firebaseApp.auth() is now replaced by a single getAuth() function in version 9, which returns an Authentication instance using firebaseApp. This means that web apps built with version 8 or earlier will need to be refactored to utilize version 9's modular approach. Firebase offers compatibility libraries to help ease this transition in version 9.

You should update your imports:

Before: version 8

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

After: version 9 compat

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

You can also refactor your code according to the modular style, which differs slightly from the compat version. Detailed documentation on these differences is available here. Make sure to review it for a better understanding.

Answer №2

Additionally, it is important to take note of the information provided here.

It is crucial to remember that the compat libraries are only a short-term fix and will be completely phased out in upcoming major SDK versions (like version 10 or version 11). The ultimate goal is to eliminate compat code entirely and transition to version 9 modular-style code in your application.

Hence, "compat" serves as an interim solution to facilitate the compatibility of your v8 code with v9, requiring minimal modifications. Eventually, transitioning to a modular style is imperative.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Why do referees attempt to access fields directly instead of using getters and setters?

I am facing an issue with my TypeScript class implementation: class FooClass { private _Id:number=0 ; private _PrCode: number =0; public get Id(): number { return this._Id; } public set Id(id: number) { this._Idprod ...

Experience seamless music playback using Howler and NextJS, effortlessly playing one song after another

I recently encountered an issue while trying to play a list of songs stored on github. My goal was to play each song sequentially and print a message in the console once a song finishes playing. However, I struggled with determining when a song is finish ...

NextJS and AWS Amplify collaboration for secure authentication routing

After hours of research, I'm struggling to navigate the authentication routing in NextJS combined with AWS Amplify. As a newcomer to NextJS, I want to implement a feature that disables the login/register page for users who are already logged in and pr ...

Securing your Angular application with user authentication and route guarding ensures

In the process of developing an Angular single-page application (SPA) front-end that interacts with a GraphQL endpoint, I encountered a challenge. Upon user login, I store the token in local storage and update the authentication state in my AuthService com ...

Utilizing arrays to generate dynamic types within a class method

Is there a way to extract values from an array as specific types in TypeScript? const chars = ['a','b','c'] as const type TChars = typeof chars[number] // 'a'| 'b' | 'c' I want to achieve the sa ...

Rect cannot be resized using mouse events

I am currently working on resizing the rectangle inside the SVG using mouse events. To achieve this, I have created another circle shape at the right bottom edge of the rectangle and implemented resize events on that shape. However, I'm facing an issu ...

conditional operator that compares values in router events

As I examine an object, links = { link1: 'page1', link2: 'page2', link3: 'page3', link4: 'page4', link5: 'page5', link6: 'page6' } I possess a function for retrieving t ...

Ways to resolve the issue: The property 'X' is not recognized on the '{ object }' data type

Just getting started with vuejs and encountering an error in my vue file Issue: Property 'ClientsSrv' is not recognized on type '{ name: string; props: {}; data(): { ClientsSrv: ClientsService | null; ClientsList: ClientsModel[] | null; IsR ...

Transform string enum type into a union type comprising enum values

Is there a way to obtain a union type from a typescript string enum? enum MyEnum { A = 'a', // The values are different from the keys, so keyof will not provide a solution. B = 'b', } When working with an enum type like the one sh ...

Angular form field not connected to data source

Here is a form I'm working with: <form #appForm> <div...> <select id="transversal" name="transversal" [ngModel]="app.transversal" type="select" required #transversal="ngModel"> < ...

Utilizing getStaticProps data in a Leaflet Canvas Layer within Next.js

Currently, I am exploring Next.js and encountering challenges when trying to access the output of one of my API routes using getStaticProps. The functional API route is causing an undefined result when I use console.log on the props object within my compon ...

Issue with displaying Angular index.html page post-build

My Angular application runs smoothly on ng serve, but after building and uploading with ng build --prod, the index.html file fails to open. I've tried using various base href configurations like <base href="#">, <base href="/& ...

Confirming an android purchase through the use of Firebase cloud function and Firestore

I've been developing a new method for verifying purchases on an Android device. I came across this code snippet that utilizes Firebase's realtime database, but I'm looking to implement it using Firebase Firestore instead: const functions = ...

Exploring ways to retrieve the result of a function within Next.js?

I'm in the process of creating a website using Vercel and Next.js. The initial step involved utilizing a template from Next.js. One of the functions within my project is responsible for extracting strings from a Google Sheets spreadsheet. This partic ...

Tips for translating or localizing Material-UI (MUI) 5 DatePicker

How can I change the text of the OK and Cancel buttons in Material UI 5? It seems like there is no direct option to do so. In Material-Ui 4, this was possible by using these props: okLabel="تأیید" cancelLabel="لغو" clearLabel=& ...

Difficulty with implementing Next.js i18n routing within a Docker environment

I'm currently working on implementing the integrated internationalized routing feature of Next.js. After following the provided tutorial, I have managed to integrate the official example code into my project successfully. This functionality is workin ...

Typescript library available as a private npm dependency

I have developed a Typescript library that I bundle as an npm module. During the development of my frontend application, I easily integrated this library using yarn link. As I set up GitLab CI for other developers to work on the frontend application, I am ...

[next-auth][error][client_fetch_error] NextAuthJS CredentialsProvider "providers SyntaxError: Invalid JSON format at position 0"

When I first started using Next.js, I discovered NextAuthJS as a way to implement custom email and password authentication. I decided to go with the Credentials Provider and set it up as shown below: import NextAuth from "next-auth"; import Crede ...

No data is being recorded in the Firestore database

This component in nextjs is designed to write data to a firestore database after the user clicks a button. Unfortunately, Firebase seems to be having trouble writing the data, even though the alert message following the supposed data dump is successful. I ...

What is the best way to use Immer to update Zustand state when incorporating objects that are added through a controlled form using React-Hook-

Having some trouble with integrating Zustand and Immer using React-Hook-Form. My goal is to capture a series of values from a form, store them in a list, and allow for the addition of new objects to that list. In this scenario, the user inputs data for a ...