'Firebase Cloud Messaging Web - onMessage not firing

I am trying to integrate FCM into my Next.js app. I have a hook to handle the messaging, but it isn't receiving my test messages. The code produces no errors either client side or server side, and logging shows that the onMessage callback is set, but after calling the API to send a test message, the client does not execute the callback.

_app.tsx

export default function MyApp({ Component, pageProps }: AppProps) {
    initializeFirebase();
    useMessaging();

    return <Component {...pageProps} />;
}

hooks.ts

export function useMessaging() {
    const [user] = useAuthState(getAuth());
    const [token, setToken] = useState<string | null>(null);

    useEffect(() => {
        // VAPID_KEY is imported from another file
        getToken(getMessaging(), { vapidKey: VAPID_KEY })
            .then((token) => {
                setToken(token);
                onMessage(getMessaging(), (message) => {
                    // For testing, log that the message was received
                    console.log({ message });
                });
            })
    }, []);

    useEffect(() => {
        if (user && token) {
            // For testing, log the token
            console.log({ token });
        }
    }, [user, token]);
}

/api/test.ts

export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse
) {
    const serviceAccount = JSON.parse(
        decodeURI((process.env as MoodGraphEnv).FIREBASE_SERVICE_ACCOUNT)
    ) as ServiceAccount;

    if (getApps().length === 0) {
        initializeApp({
            credential: cert(serviceAccount),
            databaseURL: 'https://my-app-123456-default-rtdb.firebaseio.com',
        });
    }

    const message: Message = {
        notification: {
            title: 'Hello world!',
            body: 'The notification worked!',
        },
        token:
            // During testing I replace this with the token logged to the browser console
            'token_goes_here',
    };

    getMessaging()
        .send(message)
        .then((messagingResponse) => {
            console.log('Successfully sent message:', messagingResponse);
        })
        .catch((error) => {
            console.log('Error sending message:', error);
        });

    res.status(200).json({});
}

I am not sure why the callback is not executed, so any help would be appreciated.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source