简体   繁体   中英

error in firebase function, Firebase: No Firebase App '[DEFAULT]' has been created

I'm trying to interact with the database in a function, but I'm getting an error when trying to use the doc() function within a firebase function

The error im getting is: " Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app). "

See the code below and the function I'm getting the error on. Im guessing in has something to do with not being able to use the db variable? But if I cant do that, how do I interact with the database?

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import {
  collectionGroup, doc, getDoc,
  getDocs,
  getFirestore,
  query,
} from "firebase/firestore";

// Sendgrid Config
import sgMail from "@sendgrid/mail";
import {
  ClientUserData,
  Course,
  EventType,
  Task,
} from "../../src/views/types/interfaces";

import {startOfDay} from "date-fns";

const adminApp = admin.initializeApp();
const auth = adminApp.auth();
const db = getFirestore();


//THE FUNCTION IT FAILS ON
export const checkCourseForNewClientProgram = functions.pubsub.schedule("Every day").onRun(async () => {
  const courses: Course[] = [];
  const coursesByCompanies = query(collectionGroup(db, "courses"));
  // eslint-disable-next-line max-len
  const checkCourseForNewClientProgramSnapshot = await getDocs(coursesByCompanies);
  checkCourseForNewClientProgramSnapshot.forEach((courseSnapshot) => {
    const course = courseSnapshot.data() as Course;
    if (course.events && course.events.length > 0) {
      const courseEvents = course.events;
      const todayDate = startOfDay(new Date()).getTime();
      courseEvents.forEach((event) => {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        // eslint-disable-next-line max-len
        const eventStart = convertFirebaseDateIntoJSDate(event.start.seconds).getTime();
        if (todayDate === eventStart) {
          courses.push(course);
        }

        if (event.type === EventType.TASK) {
          const eventLessons = (event as Task).lessons;
          if (eventLessons && eventLessons.length > 0) {
            eventLessons.forEach((eventLesson) => {
              // eslint-disable-next-line @typescript-eslint/ban-ts-comment
              // @ts-ignore
              // eslint-disable-next-line max-len
              const lessonStart = convertFirebaseDateIntoJSDate(eventLesson.start.seconds).getTime();
              if (todayDate === lessonStart) {
                courses.push(course);
              }
            });
          }
        }
      });
    }
  });
  let userIds: string[] = [];
  courses.forEach((course) => {
    if (course.users) {
      userIds = course.users.map((userId) => userId);
    }
  });

  const userEmails = await Promise.all(
      userIds.map(async (userId) => {
        // eslint-disable-next-line max-len
        const userData = await getDocumentFromId<ClientUserData>("company_clients", userId);
        return userData.email;
      })
  );

  await Promise.all(
      userEmails.map(async (userEmail) => {
        const msg = {
          to: userEmail,
          from: "nicky@byplayart.dk",
          templateId: "d-8609d087e96e42d5abe6991d19afb22d",
          dynamic_template_data: {
            email: userEmail,
            toName: "Testing tasks",
            fromName: "Unlimited Performance",
            subject: "Du har en opgave der venter",
            text: "Dette er din tekst",
          },
        };

        try {
          await sgMail.send(msg);
          return {
            success: true,
          };
        } catch (e) {
          return {
            success: false,
            error: e,
          };
        }
      })
  );
});

With the Admin SDK version 9 you should use the namespaced syntax, similarly to the Client SDK v8 . The corresponding reference for the Admin DSK is actually the Node.js one .

Your code should then been adapted as follows:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
    
admin.initializeApp();
    
const db = admin.firestore();
    
    
export const checkCourseForNewClientProgram = functions.pubsub.schedule("Every day").onRun(async () => {});
        
  const coursesByCompanies = db.collectionGroup("courses");
  const checkCourseForNewClientProgramSnapshot = await coursesByCompanies.get();

  checkCourseForNewClientProgramSnapshot.forEach((courseSnapshot) => {...});
    
   //...
      
   return null;
        
});

Don't forget to correctly terminate your Cloud Function, either by returning the Promise returned by the last Promise.all() call or a value (eg return null; ) after all the asynchronous work is complete. This is a key point and I would suggest you read this part of the doc and watch the 3 videos about "JavaScript Promises" from the Firebase video series .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM