firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.81k stars 883 forks source link

This browser doesn't support the API requested to use by Firebase SDK #8372

Closed kamizx786 closed 1 month ago

kamizx786 commented 1 month ago

Operating System

Android IOS

Browser Version

Chrome,Safari

Firebase SDK Version

10.12.3

Firebase SDK Product:

Messaging

Describe your project's tooling

Nextjs

Describe the problem

I'm working on a project where I have a React web app that is embedded within a React Native WebView. I'm using Firebase Cloud Messaging (FCM) for handling notifications. The web app works fine when deployed on a secure domain (https://), but when I open the same web app in a WebView in my React Native app, I encounter the following error:

This browser doesn't support the API requested to use by Firebase SDK

This code works perfectly in the web browser but fails when the web app is loaded within the WebView of my React Native app.

Steps and code to reproduce issue

import { useEffect } from 'react';
import firebase from 'firebase/app';
import 'firebase/messaging';
import axios from 'axios';

const firebaseConfig = {
  // Edit: removed user's project details.
};

firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();

export const requestNotificationPermission = async () => {
  try {
    const permission = await Notification.requestPermission();
    if (permission === 'granted') {
      console.log('Notification permission granted.');
      getDeviceToken();
    } else {
      console.log('Notification permission denied.');
    }
  } catch (error) {
    console.error('Error requesting notification permission:', error);
  }
};

const getDeviceToken = async () => {
  try {
    const currentToken = await messaging.getToken({
      vapidKey: process.env.NEXT_PUBLIC_SERVER_KEY,
    });
    if (currentToken) {
      console.log('Device token:', currentToken);
      saveTokenToLocalStorage(currentToken);
      saveTokenToDb(currentToken);
    } else {
      console.log('No registration token available.');
    }
  } catch (error) {
    console.error('Error getting device token:', error);
  }
};

const saveTokenToLocalStorage = (token: string) => {
  localStorage.setItem('device_token', JSON.stringify(token));
  console.log('Token saved to local storage.');
};

const saveTokenToDb = async (token: string) => {
  try {
    const response = await axios.post('/v1/user/token', {
      deviceToken: token,
    });
    console.log('Token saved to database:', response.data);
  } catch (error) {
    console.error('Error saving token to database:', error);
  }
};
hsubox76 commented 1 month ago

I'm unfamiliar with React Native WebViews but this is the check that runs that leads to that error if any of these conditions fail:

https://github.com/firebase/firebase-js-sdk/blob/master/packages/messaging/src/api/isSupported.ts#L42

    typeof window !== 'undefined' &&
    isIndexedDBAvailable() &&
    areCookiesEnabled() &&
    'serviceWorker' in navigator &&
    'PushManager' in window &&
    'Notification' in window &&
    'fetch' in window &&
    ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
    PushSubscription.prototype.hasOwnProperty('getKey')

Those are the APIs that the messaging SDK requires, and it seems one of those fails in your React Native WebView environment. You can try to pinpoint which one by running those checks one-by-one yourself in your own code. If you can identify which one, you may be able to polyfill it, but some of them may not be possible to polyfill or work around.

Let us know if you identify which condition(s) fail and if you think it's a false positive somehow. Otherwise it would seem FCM is not supported in this environment.

kamizx786 commented 1 month ago

So I Try to Test and got to know in React native web view These conditions are failing

'serviceWorker' in navigator && 'PushManager' in window && 'Notification' in window &&

hsubox76 commented 1 month ago

If these APIs do not exist in this environment, the FCM web SDK won't be able to work and is unsupported in that environment. If you want to use FCM in React Native, you'll have to find another method such as React Native Firebase.