我试图在函数中与数据库交互,但在firebase函数中尝试使用doc((函数时出错
我得到的错误是:"Firebase:尚未创建任何Firebase应用程序"[DEFAULT]"-调用Firebase App.initializeApp(((App/No-App(。">
请参阅下面的代码和我得到错误的函数。我猜in与不能使用db变量有关?但如果我不能做到这一点,我该如何与数据库交互?
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,
};
}
})
);
});
对于Admin SDK版本9,您应该使用名称空间语法,类似于Client SDK版本8。Admin DSK的相应引用实际上是Node.js。
然后,您的代码应该进行如下调整:
import * as functions from "firebase-functions";
import * as admin from "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;
});
不要忘记在所有异步工作完成后,通过返回上一次Promise.all()
调用返回的Promise或值(例如return null;
(来正确终止您的云函数。这是一个关键点,我建议你阅读文档的这一部分,并观看关于";JavaScript承诺";来自Firebase系列视频。