Skip to content

Commit f4c37f5

Browse files
committed
Fix Firebase build initialization
1 parent 6342833 commit f4c37f5

3 files changed

Lines changed: 45 additions & 15 deletions

File tree

src/app/api/notifications/mass-notification/route.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import { NextRequest, NextResponse } from 'next/server'
2-
import webpush, { WebPushError } from 'web-push'
3-
import { messaging } from 'firebase-admin'
42
import { sendNotification } from '@/server/notifications'
53
import prisma from '@/server/db'
64
import { withLogging, logger } from '@/server/logger'

src/server/firebase.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,34 @@
1-
import admin, { ServiceAccount } from 'firebase-admin'
1+
import { App, cert, getApps, initializeApp } from 'firebase-admin/app'
2+
import { getMessaging } from 'firebase-admin/messaging'
23

3-
const serviceAccount = process.env.GOOGLE_SERVICES_JSON ? JSON.parse(process.env.GOOGLE_SERVICES_JSON) : null
4+
function getServiceAccount() {
5+
const rawServiceAccount = process.env.GOOGLE_SERVICES_JSON
46

5-
if (!admin.apps.length && serviceAccount) {
6-
admin.initializeApp({
7-
credential: admin.credential.cert(serviceAccount as ServiceAccount),
7+
if (!rawServiceAccount) {
8+
return null
9+
}
10+
11+
return JSON.parse(rawServiceAccount)
12+
}
13+
14+
export function getFirebaseApp(): App {
15+
const existingApp = getApps()[0]
16+
17+
if (existingApp) {
18+
return existingApp
19+
}
20+
21+
const serviceAccount = getServiceAccount()
22+
23+
if (!serviceAccount) {
24+
throw new Error('Firebase Admin is not configured. Set GOOGLE_SERVICES_JSON before using FCM.')
25+
}
26+
27+
return initializeApp({
28+
credential: cert(serviceAccount),
829
})
930
}
1031

11-
export const messaging = admin.messaging()
32+
export function getFirebaseMessaging() {
33+
return getMessaging(getFirebaseApp())
34+
}

src/server/notifications.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
import webpush, { WebPushError } from 'web-push'
2-
import { messaging } from '@/server/firebase'
2+
import { getFirebaseMessaging } from '@/server/firebase'
33
//import { Subscription } from '@prisma/client'
44
//import { JsonValue } from '@prisma/client/runtime/library'
55
import prisma from '@/server/db'
66
import { logger } from '@/server/logger'
77
import { Prisma, Subscription } from '../generated/prisma/client'
88

9-
// Initialize VAPID keys for web push notifications
10-
webpush.setVapidDetails(
11-
'mailto:your-email@example.com',
12-
process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
13-
process.env.VAPID_PRIVATE_KEY!
14-
)
9+
function configureWebPush() {
10+
const publicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY
11+
const privateKey = process.env.VAPID_PRIVATE_KEY
12+
13+
if (!publicKey || !privateKey) {
14+
throw new Error(
15+
'Web push is not configured. Set NEXT_PUBLIC_VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY.'
16+
)
17+
}
18+
19+
webpush.setVapidDetails('mailto:your-email@example.com', publicKey, privateKey)
20+
}
1521

1622
/**
1723
* The payload for the notification, including title, body, url, icon, and badge.
@@ -33,6 +39,8 @@ export async function sendNotification(
3339
try {
3440
logger.info('Sending notification to subscription:', subscription)
3541
if (subscription.type === 'web') {
42+
configureWebPush()
43+
3644
if (!isWebKeys(subscription.keys)) {
3745
throw new Error(`Invalid keys for web subscription: ${JSON.stringify(subscription.keys)}`)
3846
}
@@ -56,6 +64,7 @@ export async function sendNotification(
5664
if (!isFcmKeys(subscription.keys)) {
5765
throw new Error(`Invalid keys for FCM subscription: ${JSON.stringify(subscription.keys)}`)
5866
}
67+
const messaging = getFirebaseMessaging()
5968
const fcmMessage = {
6069
notification: {
6170
title: notificationPayload.title,

0 commit comments

Comments
 (0)