firebase / firebase-js-sdk

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

FR: Use fetch in firebase/storage instead of XMLHttpRequest #6595

Open poltak opened 1 year ago

poltak commented 1 year ago

[REQUIRED] Describe your environment

[REQUIRED] Describe the problem

I'm trying to use v9 SDK exported firebase/storage methods like uploadString, uploadByte within the context of a manifest v3 Chrome extension's Service Worker. Service workers lack the XMLHttpRequest web API, which is used to implement the network request part of these methods. See the following line in the source code for where the XMLHttpRequest API is used: https://github.com/firebase/firebase-js-sdk/blob/master/packages/storage/src/platform/browser/connection.ts#L42

I saw similar issues about other parts of the FB web SDK, which resulted in the the move to use fetch API for this implementation, and was wondering if it could be done for this storage logic too, to afford service worker/MV3 extension support?

I haven't included any reproducible example, as I think it is fairly clear from the above linked line in the source code and the fact that Service Workers don't support XMLHttpRequest. Though please let me know if you need any further info

Related issues:

maneesht commented 1 year ago

Hi @poltak - this is something we are looking into, but do not have an ETA for. Thank you for filing this.

poltak commented 1 year ago

Good to hear @maneesht

For anyone stumbling onto this issue with the same problem: We ended up using the xhr-shim package on NPM to polyfill global['XHMLHttpRequest'], after which firebase/storage works fine in our web extension's background service worker.

maneesht commented 1 year ago

@poltak, out of curiosity, are you attempting to use Firebase Storage for uploading files in a service worker?

poltak commented 1 year ago

Yes, via the uploadBytes and uploadString methods

maneesht commented 1 year ago

@poltak xhr-shim doesn't allow for progress events, is that not part of your use-case?

poltak commented 1 year ago

No it's currently not part of our use-case. Many of these uploads can happen as part of longer running "sync" function, where we currently only count each as pending or done.

maneesht commented 1 year ago

@poltak Thank you for describing this.

As upload status is not widely supported and is a critical feature for Firebase Storage, we cannot switch over to use fetch at this time. We will revisit this when proper browser support has been added.

poltak commented 1 year ago

I see. As I didn't need to use this feature, I didn't realize it was a limitation of the fetch API until now. A bit of a reading around tells me it is an ongoing discussion in different browsers (for ref: try googling "ReadableStream as Request.body in fetch API"). Hopefully there's wider support in the near future. Thanks for the clear comms @maneesht !

umrashrf commented 11 months ago

Just ran into this issue with Chrome Extension V3 environment. The service worker of Chrome Extension V3 no longer supports XMLHttpRequest and has fetch().

"dependencies": {
    "firebase": "^10.1.0",
shamoons commented 9 months ago

Same issue: "firebase": "^10.3.1",

Georg7 commented 9 months ago

Same issue. Using "firebase": "^10.4.0"

chirag-chhajed commented 8 months ago

I am not using firebase/storage but I was getting a similar issue for firebase/firestore and I think I have found a workaround for it without using xhr-shim package.

I am using vite + react +@crxjs/vite-plugin In you chrome extension's web worker file initialize your firebase app

import { initializeApp } from "firebase/app";
import {
  collection,
  getFirestore,
} from "firebase/firestore";

const firebaseConfig = yourConfig; // Replace with your Firebase configuration

// Initialize the Firebase app
export const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

// Export the reference to the Firestore collection you want to interact with
export const siteRef = collection(db, "sites"); // Replace "sites" with your collection name

Now where in your react app, you want to make a request import addDoc, Timestamp

import { addDoc, Timestamp } from "firebase/firestore";

  const onSubmit = async (data: SiteData): Promise<void> => {
    try {
      const res = await addDoc(siteRef, {
        ...data,
        url: debouncedUrl,
        user_id: user?.uid,
        favicon: faviconURL(data.url),
        created_at: Timestamp.now(),
        updated_at: Timestamp.now(),
      });

      console.log("added to db", res);
      toast.success("Site Added");
      form.reset();
    } catch (err) {
      console.error(err);
      toast.error("Failed to add the site");
    }
  };

and this code works fine, there's no XMLHttpRequest not defined error because we are not making the request in the Web worker

Boogaloo-XT commented 7 months ago

Same issue. Using "firebase": "^10.5.2"

Akisazaki commented 7 months ago

Same issue. Using "firebase": "^10.6.0"

MishaMgla commented 6 months ago

Same issue with "firebase": "^10.6.0", trying UploadBytes() in background extension script.

Good to hear @maneesht

For anyone stumbling onto this issue with the same problem: We ended up using the xhr-shim package on NPM to polyfill global['XHMLHttpRequest'], after which firebase/storage works fine in our web extension's background service worker.

Would you mind to share how to use xhr-shim properly? I have imported it in my background script, but it still gives XHR not found error. It seems like xhr-shim not polyfilling properly xhr

poltak commented 6 months ago

@MishaMgla you should only need something like this in your entry point file's top-level scope:

import XMLHttpRequest from 'xhr-shim'

global['XMLHttpRequest'] = XMLHttpRequest

I'm on 0.1.2 of the package

MishaMgla commented 6 months ago

@MishaMgla you should only need something like this in your entry point file's top-level scope:

import XMLHttpRequest from 'xhr-shim'

global['XMLHttpRequest'] = XMLHttpRequest

I'm on 0.1.2 of the package

Thank you! Your advice helped me a lot!

CarrizalViaro commented 2 months ago

@MishaMgla you should only need something like this in your entry point file's top-level scope:

import XMLHttpRequest from 'xhr-shim'

global['XMLHttpRequest'] = XMLHttpRequest

I'm on 0.1.2 of the package

I try this, but i get this: ReferenceError: global is not defined I added it in my backgrund file on top Manifest V3

MishaMgla commented 2 months ago

@MishaMgla you should only need something like this in your entry point file's top-level scope:

import XMLHttpRequest from 'xhr-shim'

global['XMLHttpRequest'] = XMLHttpRequest

I'm on 0.1.2 of the package

I try this, but i get this: ReferenceError: global is not defined I added it in my backgrund file on top Manifest V3

For me this worked

import XMLHttpRequest from 'xhr-shim'; self['XMLHttpRequest'] = XMLHttpRequest;

Viaro-Brayan-Aguirre commented 2 months ago

Same issue with firebase 10.10.0 on Chrome Extension Manifest V3. We found a work around with xhr-shim but Firebase needs to support a new way with fetch or something similar to work with Manifest V3 on Chrome. Firebase is a great way to develop applications quickly and with this they are leaving all of us who develop applications in Chrome extension without support. Furthermore, the extensions are not only for Chrome, but for Opera, Edge and countless Chromium-based browsers.