55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import admin from "firebase-admin";
|
|
import type { ServiceAccount } from "firebase-admin/app";
|
|
import type { Messaging } from "firebase-admin/messaging";
|
|
import { log } from "../util/log.js";
|
|
|
|
type ServiceAccountJson = ServiceAccount & { project_id?: string };
|
|
|
|
function serviceAccountProjectId(account: ServiceAccountJson): string | undefined {
|
|
if (typeof account.projectId === "string" && account.projectId.length > 0) {
|
|
return account.projectId;
|
|
}
|
|
if (typeof account.project_id === "string" && account.project_id.length > 0) {
|
|
return account.project_id;
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
function resolveCredential(): admin.credential.Credential {
|
|
const json = process.env.FIREBASE_SERVICE_ACCOUNT_JSON;
|
|
if (json !== undefined && json.trim() !== "") {
|
|
let account: ServiceAccountJson;
|
|
try {
|
|
account = JSON.parse(json) as ServiceAccountJson;
|
|
} catch (err) {
|
|
const message = err instanceof Error ? err.message : String(err);
|
|
log.error(
|
|
"[Firebase] FIREBASE_SERVICE_ACCOUNT_JSON parse failed:",
|
|
message
|
|
);
|
|
throw err;
|
|
}
|
|
const projectId = serviceAccountProjectId(account);
|
|
log.info(
|
|
"[Firebase] Credential: FIREBASE_SERVICE_ACCOUNT_JSON (parsed successfully)"
|
|
);
|
|
if (projectId !== undefined) {
|
|
log.info("[Firebase] project_id:", projectId);
|
|
} else {
|
|
log.info("[Firebase] project_id: (not found in service account JSON)");
|
|
}
|
|
return admin.credential.cert(account);
|
|
}
|
|
|
|
log.info("[Firebase] Credential: Application Default Credentials");
|
|
return admin.credential.applicationDefault();
|
|
}
|
|
|
|
if (!admin.apps.length) {
|
|
admin.initializeApp({
|
|
credential: resolveCredential(),
|
|
});
|
|
}
|
|
|
|
export const messaging: Messaging = admin.messaging();
|