quickstart-js icon indicating copy to clipboard operation
quickstart-js copied to clipboard

Impossible to use Firebase React with Manifest v3

Open ctjlewis opened this issue 2 years ago • 22 comments

Summary

It is not possible to use Firebase React in Chrome extension content scripts using manifest v3 because the CSP settings that Firebase requires to work are prohibited by Chrome's new CSP policies. Since it is no longer possible to publish new MV2 extensions, new extensions are unable to use Firebase in their documents (e.g. popup window).

Original post

I have had the unique pleasure of trying to package a Firebase-enabled application as a Chrome extension, only to find that with manifest v3 the only way to do this is in a service worker, which comes with great limitations on how users can authorize with Firebase Auth and so on.

It is important that Google's own Chrome Extensions ecosystem is compatible with Google's own Firebase software, but I am not shocked to see the attempt to force developers to break their own apps before January 2022 when this team intends to deprecate manifest v2 even though this will preclude future extensions from integrating Google's own technology.

Peep the comments of this video for some examples of how distraught developers are about this issue, and plenty similar posts exist on StackOverflow as well:

https://www.youtube.com/watch?v=UjH2INUPmF4

What do?

ctjlewis avatar Dec 30 '21 02:12 ctjlewis

cc @jamesdaniels

ctjlewis avatar Dec 30 '21 03:12 ctjlewis

Specifically, https://firebaseopensource.com/projects/firebase/quickstart-js/auth/chromextension/readme/ does no longer work in MV3, in this case not because serviceworker restrictions per se, but because the extension has no rights to open a popup window. Would it be better to open a new issue for that ?

klapauciusisgreat avatar Jan 25 '22 01:01 klapauciusisgreat

Does anyone know this problem will be solved?

yankovichv avatar Feb 06 '22 19:02 yankovichv

+1 https://firebase.google.com/docs/auth/web/github-auth#authenticate_with_firebase_in_a_chrome_extension

bang9 avatar Feb 15 '22 19:02 bang9

~~Is there really no guidance on using Firebase Auth in a Chrome extension with mv3 now? CWS has already disallowed new v2 submissions; are we to just suspend development?~~

Thought I suspect most know this and doesn't solve for the popup problem, perhaps this is useful for others searching. Firebase Auth works from a manifest v3 service worker using signInWithCredential:

  1. Use chrome.identity.getAuthToken() to retrieve the auth token for the user.
  2. Generate a credential via GoogleAuthProvider.credential().
  3. Pass that credential to signInWithCredential().

ibejoeb avatar Mar 02 '22 02:03 ibejoeb

~Is there really no guidance on using Firebase Auth in a Chrome extension with mv3 now? CWS has already disallowed new v2 submissions; are we to just suspend development?~

Thought I suspect most know this and doesn't solve for the popup problem, perhaps this is useful for others searching. Firebase Auth works from a manifest v3 service worker using signInWithCredential:

  1. Use chrome.identity.getAuthToken() to retrieve the auth token for the user.
  2. Generate a credential via GoogleAuthProvider.credential().
  3. Pass that credential to signInWithCredential().

Thanks for the help! Before adding the sign in feature, I will need to add fireabase to the extension. Can you please let me know how did you connect firebase to mv3 chrome extension? I checked a lot of websites online, but majority of them are in mv2 & if found in mv3, they are faulty ones. Can you please let me know how did you make the connection?

vedantbothikar avatar May 21 '22 16:05 vedantbothikar

Hey , did by any chance find a solution to add firebase in V3

paraschhugani avatar Jun 11 '22 11:06 paraschhugani

Hey , did by any chance find a solution to add firebase in V3

Not yet

vedantbothikar avatar Jun 11 '22 11:06 vedantbothikar

As I pointed out in the OP, it is not possible to use Firebase at all in a Manifest v3 extension because the CSP policies that Firebase requires are prohibited by the CSP policies that control Chrome extensions in v3. It cannot be done without updating the library's logic itself.

ctjlewis avatar Jun 11 '22 11:06 ctjlewis

@ctjlewis

it is not possible to use Firebase at all in a Manifest v3 extension

I use it. What features are you trying to use? I use auth, firestore, and functions. Here's an implementation of the general idea that I proposed above:

// in the service worker

import { initializeApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider, signInWithCredential, User } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getFunctions } from 'firebase/functions';

const firebaseConfig = {
  // your config
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const functions = getFunctions(app);

const getGoogleAuthCredential = () => {
  return new Promise<ReturnType<typeof GoogleAuthProvider.credential>>((resolve, reject) => {
    chrome.identity.getAuthToken({ interactive: true }, token => {
      if (chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError);
        reject(chrome.runtime.lastError);
      }
      const credential = GoogleAuthProvider.credential(null, token);
      resolve(credential);
    });
  });
};

const signIn = async () => {
  try {
    const credential = await getGoogleAuthCredential();
    const result = await signInWithCredential(auth, credential);
    return result.user;
  } catch (e) {
    console.error(e);
    return null;
  }
};

This requires the indentity permission in manifest.json, e.g.:

{
  "manifest_version": 3,
  "permissions": [ "identity" ]
}

@master30112001

how did you make the connection?

Do all communications from the service worker and then pass messages with your data between that and content, popup, devtools, etc.

ibejoeb avatar Jun 11 '22 12:06 ibejoeb

@ibejoeb

Can you please make a repository having firebase connections with google authentication?(in mv3)

Your repo would be very helpful to use as a starter template for our projects

vedantbothikar avatar Jun 11 '22 13:06 vedantbothikar

+1 https://firebase.google.com/docs/auth/web/github-auth#authenticate_with_firebase_in_a_chrome_extension

This is not possible because there is no way to allow external hosts in the CSP with V3. What may work is using chrome.identity API (stackoverflow) with firebase auth which won't invoke any firebase popups or redirects which are no longer possible in MV3.

elhardoum avatar Jun 13 '22 02:06 elhardoum

This is documented. It may not have been when this issue was opened, but it is now acknowledged that certain auth features are not available:

from https://firebase.google.com/docs/web/environments-js-sdk#auth-note:

All Authentication features, except phone authentication and popup/redirect OAuth operations, are supported.

There are limitations on using Auth. But it is not "Impossible to use Firebase with Manifest v3."

ibejoeb avatar Jun 13 '22 03:06 ibejoeb

@ibejoeb - I was specifically referring to Firebase React in a popup window. I edited to clarify.

ctjlewis avatar Jun 13 '22 07:06 ctjlewis

One temporary fix is that we can make an API on firebase functions. Is there any other workaround for it?

Atharv777 avatar Jul 24 '22 14:07 Atharv777

Is this solved?

MakingStan avatar Aug 02 '22 08:08 MakingStan

How can I use signInWithPhoneNumber in chrome extension react?

ghost avatar Aug 02 '22 14:08 ghost

using chrome.identity will prohibit us from using it in Microsoft edge extension.

mohanish2504 avatar Dec 07 '22 18:12 mohanish2504

any updates anywhere on using firebase with MV3 ?

fablorv avatar Dec 29 '22 03:12 fablorv

Any updates or workaround on the issue except using chrome.identity?

dbjpanda avatar Feb 23 '23 15:02 dbjpanda

I used code above from @ibejoeb with this boilerplate https://github.com/guocaoyi/create-chrome-ext/tree/main:

// Import the functions you need from the SDKs you need
import { initializeApp } from 'firebase/app'
import {
  getAuth,
  signInWithPopup,
  GoogleAuthProvider,
  signInWithRedirect,
  signInWithCredential,
} from 'firebase/auth'
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
///...
}

// Initialize Firebase
const app = initializeApp(firebaseConfig)
const auth = getAuth(app)

const getGoogleAuthCredential = () => {
  return new Promise<ReturnType<typeof GoogleAuthProvider.credential>>((resolve, reject) => {
    chrome.identity.getAuthToken({ interactive: true }, (token) => {
      if (chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError)
        reject(chrome.runtime.lastError)
      }
      const credential = GoogleAuthProvider.credential(null, token)
      resolve(credential)
    })
  })
}

const signIn = async () => {
  try {
    const credential = await getGoogleAuthCredential()
    const result = await signInWithCredential(auth, credential)
    return result.user
  } catch (e) {
    console.error(e)
    return null
  }
}

;(async () => {
  debugger
  console.log('users', await signIn())
})()

chrome.runtime.onMessage.addListener((request) => {
  if (request.type === 'COUNT') {
    console.log('background has received a message from popup, and count is ', request?.count)
  }
})

Make sure that you have uploaded your extension to store and a key property:

"oauth2": {
    "client_id": "YOUR_EXTENSION_OAUTH_ID.apps.googleusercontent.com",


    "scopes": [
      "https://www.googleapis.com/auth/userinfo.email",
      "https://www.googleapis.com/auth/userinfo.profile"
    ]
  },
"key":"ThisKeyIsGoingToBeVeryLong/go8GGC2u3UD9WI3MkmBgyiDPP2OreImEQhPvwpliioUMJmERZK3zPAx72z8MDvGp7Fx7ZlzuZpL4yyp4zXBI+MUhFGoqEh32oYnm4qkS4JpjWva5Ktn4YpAWxd4pSCVs8I4MZms20+yx5OlnlmWQEwQiiIwPPwG1e1jRw0Ak5duPpE3uysVGZXkGhC5FyOFM+oVXwc1kMqrrKnQiMJ3lgh59LjkX4z1cDNX3MomyUMJ+I+DaWC2VdHggB74BNANSd+zkPQeNKg3o7FetlDJya1bk8ofdNBARxHFMBtMXu/ONfCT3Q2kCY9gZDRktmNRiHG/1cXhkIcN1RWrbsCkwIDAQAB" 
Screenshot 2023-11-06 at 19 23 23

Alos create a OAuth 2.0 Cliend ID for chrome extension:

Screenshot 2023-11-06 at 19 28 56

After that allow firebase google auth interact with other client:

Screenshot 2023-11-06 at 19 30 37

Worked for me:

Screenshot 2023-11-06 at 19 34 22

dmitry-tuzenkov avatar Nov 06 '23 18:11 dmitry-tuzenkov

For future readers, here is the main reference - https://developer.chrome.com/docs/apps/app_identity/ I also made a small visual image

xerosanyam avatar Jan 23 '24 16:01 xerosanyam