skip to Main Content

I have a problem with my app connecting to my Firestore database when trying to use setDoc.

I have the database up and running for next-auth which is functioning as intended and creating records in the database. However, when I try and allow the rest of my app to use the database I cannot get the data to update.

I believe the problem could be to do with my config file not firing correctly but its hard to know for sure as I am not getting any errors. The onClick fires (tested) and the update does not occur.

I will provide some console screenshots and code to try and make clear the problem.

/firebase/config.js

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

const firebaseConfig = {
  apiKey: process.env.FIREBASE_API_KEY,
  appId: process.env.FIREBASE_APP_ID,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  projectId: process.env.FIREBASE_PROJECT_ID,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
};

const app = initializeApp(firebaseConfig);

const storage = getStorage(app);
const db = getFirestore(app);

export { storage, db };

Then here is my form submit to add the form field values to an existing document.

/components/signup/SignupSubmit.js

import { getSession } from "next-auth/react";
import { setDoc, doc } from "firebase/firestore";
import { db } from "../../firebase/config";

export default async function SignupSubmit(value) {
  const session = await getSession();
  const userId = session.user.id;

  const values = {
    profile: value.profile,
    screenName: value.screenName,
  };

  const docRef = doc(db, "users", `${userId}`);
  console.log(docRef);

  setDoc(docRef, { values }, { merge: true })
    .then(() => {
      console.log("Document has been updated successfully");
    })
    .catch((error) => {
      console.log(error);
    });
}

I have screenshot the output of console.log(docRef).
docRef output

Let me know if I can provide any further information as I am keen to put this issue to bed.

Thanks in advance for any and all help.

UPDATE: Here is my _app code

/pages/_app.js

import React from "react";
import { SessionProvider } from "next-auth/react";
import { SWRConfig } from "swr";

import Layout from "../components/Layout.js";
import AccountSettingsLayout from "../components/AccountSettingsLayout";

import "../styles/globals.css";

export default function App({ Component, router, pageProps }) {
  if (router.pathname.startsWith("/auth/")) {
    return (
      <React.StrictMode>
        <SessionProvider session={pageProps.session}>
          <SWRConfig>
            <AccountSettingsLayout>
              <Component {...pageProps} />
            </AccountSettingsLayout>
          </SWRConfig>
        </SessionProvider>
      </React.StrictMode>
    );
  }

  return (
    <React.StrictMode>
      <SessionProvider session={pageProps.session}>
        <SWRConfig>
          <Layout>
            <Component {...pageProps} />
          </Layout>
        </SWRConfig>
      </SessionProvider>
    </React.StrictMode>
  );
}

UPDATE – 01/10/22

I am using Next-auth in this project which is creating users and data in firebase without issue. Could this be preventing the rest of my app from using the firestore to add data?

Here is my next-auth code..

/pages/api/auth/[…nextauth].js

import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import EmailProvider from "next-auth/providers/email";
import { FirestoreAdapter } from "@next-auth/firebase-adapter";

const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
    EmailProvider({
      server: {
        host: process.env.EMAIL_SERVER_HOST,
        port: process.env.EMAIL_SERVER_PORT,
        auth: {
          user: process.env.EMAIL_SERVER_USER,
          pass: process.env.EMAIL_SERVER_PASSWORD,
        },
      },
      from: process.env.EMAIL_FROM,
    }),
  ],
  session: {
    jwt: false,
  },
  adapter: FirestoreAdapter({
    apiKey: process.env.FIREBASE_API_KEY,
    appId: process.env.FIREBASE_APP_ID,
    authDomain: process.env.FIREBASE_AUTH_DOMAIN,
    databaseURL: process.env.FIREBASE_DATABASE_URL,
    projectId: process.env.FIREBASE_PROJECT_ID,
    storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
  }),
  theme: {
    colorScheme: "dark",
  },
  pages: {
    signIn: "/auth/signin",
    newUser: "/auth/signup",
  },
  debug: false,
  callbacks: {
    async signIn({ user, account, profile }) {
      if (account.provider === "google") {
        return profile.email_verified;
      }
      return true;
    },
    async redirect({ url, baseUrl }) {
      return baseUrl;
    },
    async session({ session, user }) {
      session.user.id = user.id;
      return Promise.resolve(session);
    },
    async jwt({ token, user, account, profile, isNewUser }) {
      return token;
    },
  },
};
export default NextAuth(authOptions);

Thanks

2

Answers


  1. You are using the firebase-admin package to initialize the app, but you are using the firebase package to update the document, so you can try to use the firebase-admin package to update the document. Example:

    import { initializeApp } from "firebase/app";
    import { getFirestore } from "firebase/firestore";
    import { getStorage } from "firebase/storage";
    import { setDoc, doc } from "firebase/firestore";
    
    const firebaseConfig = {
      apiKey: process.env.FIREBASE_API_KEY,
      appId: process.env.FIREBASE_APP_ID,
      authDomain: process.env.FIREBASE_AUTH_DOMAIN,
      databaseURL: process.env.FIREBASE_DATABASE_URL,
      projectId: process.env.FIREBASE_PROJECT_ID,
      storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
      messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
    };
    
    const app = initializeApp(firebaseConfig);
    
    const storage = getStorage(app);
    const db = getFirestore(app);
    
    export { storage, db };
    
    import { db } from "../../firebase/config";
    
    export default async function SignupSubmit(value) {
    
      const values = {
        profile: value.profile,
        screenName: value.screenName,
      };
    
      const docRef = doc(db, "users", `${userId}`);
      console.log(docRef);
    
      setDoc(docRef, { values }, { merge: true })
        .then(() => {
          console.log("Document has been updated successfully");
        })
        .catch((error) => {
          console.log(error);
        });
    } 
    

    I hope this helps.

    Login or Signup to reply.
  2. I think the issue is with your env variables. In the first screenshot you get this options

    _options : ( apiKey : undefined , appId : undefined , authDomain : undefined , databaseURL : undefined
    

    Your env variables defined correctly in next-auth config, because next-auth page is pages/apis/auth/[...nextauth].js file. apis directory is executed on the server and since env variables that you set in env are by default available on the server, your configuration worked here.

    since, in the beginning yourfirestore config run on the client side, process.env.FIREBASE_API_KEY env variables were undefined. To make the env variables both available on client and server, use NEXT_PUBLIC prefix in env file.

    NEXT_PUBLIC_FIREBASE_API_KEY=#####################
    

    then use it as process.env.NEXT_PUBLIC_FIREBASE_API_KEY.

    What's the difference between exposing environment variables in nextjs through the next.config.js vs with the NEXT_PUBLIC prefix?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search