firebase-js-sdk icon indicating copy to clipboard operation
firebase-js-sdk copied to clipboard

FR: Use fetch in firebase/storage instead of XMLHttpRequest

Open poltak opened this issue 3 years ago • 20 comments

[REQUIRED] Describe your environment

  • Operating System version: macOS 12.5.1
  • Browser version: Chrome 105.0.5195.102
  • Firebase SDK version: 9.9.4
  • Firebase Product: storage

[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:

  • #6124
  • #4912
  • #6483

poltak avatar Sep 13 '22 04:09 poltak

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

maneesht avatar Sep 26 '22 20:09 maneesht

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.

poltak avatar Sep 27 '22 04:09 poltak

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

maneesht avatar Oct 28 '22 17:10 maneesht

Yes, via the uploadBytes and uploadString methods

poltak avatar Oct 29 '22 00:10 poltak

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

maneesht avatar Oct 30 '22 04:10 maneesht

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.

poltak avatar Oct 30 '22 09:10 poltak

@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.

maneesht avatar Oct 31 '22 18:10 maneesht

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 !

poltak avatar Nov 01 '22 02:11 poltak

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",

umrashrf avatar Aug 03 '23 15:08 umrashrf

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

shamoons avatar Sep 20 '23 20:09 shamoons

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

Georg7 avatar Sep 25 '23 13:09 Georg7

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

chirag-chhajed avatar Oct 11 '23 14:10 chirag-chhajed

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

Boogaloo-XT avatar Nov 08 '23 14:11 Boogaloo-XT

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

Akisazaki avatar Nov 21 '23 18:11 Akisazaki

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

MishaMgla avatar Dec 06 '23 20:12 MishaMgla

@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

poltak avatar Dec 07 '23 14:12 poltak

@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!

MishaMgla avatar Dec 09 '23 22:12 MishaMgla

@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

CarrizalViaro avatar Apr 10 '24 22:04 CarrizalViaro

@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;

MishaMgla avatar Apr 10 '24 22:04 MishaMgla

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.

Viaro-Brayan-Aguirre avatar Apr 12 '24 14:04 Viaro-Brayan-Aguirre