feat(notifications): register FCM tokens with backend
Add registerToken POST to /notifications/register (platform, testMode). Call it from Capacitor registration and Firebase getToken with deduped registerRetrievedToken; expose registerToken via barrel and useNotifications as registerFcmToken.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { inject } from "vue";
|
||||
import { NotificationIface } from "../constants/app";
|
||||
import { registerToken } from "@/services/notifications/NotificationService";
|
||||
|
||||
/**
|
||||
* Vue 3 composable for notifications
|
||||
@@ -93,5 +94,7 @@ export function useNotifications() {
|
||||
notAGive,
|
||||
notificationOff,
|
||||
downloadStarted,
|
||||
/** POST FCM token to `/notifications/register` (same as startup native hook). */
|
||||
registerFcmToken: registerToken,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,9 +14,32 @@
|
||||
*/
|
||||
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import { logger } from "@/utils/logger";
|
||||
import { NativeNotificationService } from "./NativeNotificationService";
|
||||
import { WebPushNotificationService } from "./WebPushNotificationService";
|
||||
|
||||
/**
|
||||
* Registers an FCM device token with the app backend (native Capacitor token or web getToken).
|
||||
*/
|
||||
export async function registerToken(fcmToken: string): Promise<void> {
|
||||
const res = await fetch("/notifications/register", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
fcmToken,
|
||||
platform: Capacitor.getPlatform(),
|
||||
testMode: true,
|
||||
}),
|
||||
});
|
||||
if (!res.ok) {
|
||||
logger.warn("[NotificationService] registerToken failed", {
|
||||
status: res.status,
|
||||
statusText: res.statusText,
|
||||
});
|
||||
throw new Error(`registerToken failed: HTTP ${res.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for scheduling a daily notification
|
||||
*/
|
||||
|
||||
@@ -21,11 +21,26 @@ import {
|
||||
onMessage,
|
||||
} from "firebase/messaging";
|
||||
import { logger } from "@/utils/logger";
|
||||
import { registerToken } from "./NotificationService";
|
||||
|
||||
const LOG = "[FirebaseMessaging]";
|
||||
|
||||
let firebaseAppSingleton: FirebaseApp | null = null;
|
||||
let nativeInitPromise: Promise<void> | null = null;
|
||||
/** Avoid duplicate POSTs when the same token is delivered more than once. */
|
||||
let lastRegisteredFcmToken: string | null = null;
|
||||
|
||||
async function registerRetrievedToken(token: string): Promise<void> {
|
||||
const trimmed = token.trim();
|
||||
if (!trimmed) {
|
||||
return;
|
||||
}
|
||||
if (trimmed === lastRegisteredFcmToken) {
|
||||
return;
|
||||
}
|
||||
await registerToken(trimmed);
|
||||
lastRegisteredFcmToken = trimmed;
|
||||
}
|
||||
|
||||
function readFirebaseOptions(): FirebaseOptions | null {
|
||||
const env = import.meta.env;
|
||||
@@ -107,6 +122,7 @@ async function attachFirebaseMessagingIfSupported(
|
||||
logger.info(`${LOG} Firebase getToken completed`, {
|
||||
tokenPrefix: token ? `${token.slice(0, 12)}…` : "(empty)",
|
||||
});
|
||||
await registerRetrievedToken(token);
|
||||
} catch (err) {
|
||||
logger.warn(
|
||||
`${LOG} Firebase getToken failed (common on native WebView without SW)`,
|
||||
@@ -135,6 +151,12 @@ async function initializeNativePushAndFirebaseMessagingImpl(): Promise<void> {
|
||||
logger.info(`${LOG} Capacitor registration token`, {
|
||||
valuePrefix: token.value ? `${token.value.slice(0, 12)}…` : "(empty)",
|
||||
});
|
||||
void registerRetrievedToken(token.value).catch((err) => {
|
||||
logger.warn(
|
||||
`${LOG} registerToken after Capacitor registration failed`,
|
||||
err,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
await PushNotifications.addListener("registrationError", (err) => {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
export { NotificationService } from "./NotificationService";
|
||||
export { NotificationService, registerToken } from "./NotificationService";
|
||||
export { NativeNotificationService } from "./NativeNotificationService";
|
||||
export { WebPushNotificationService } from "./WebPushNotificationService";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user