17

I have a app built with vue and firebase/firestore. I use the firebase emulator to local development and am trying to integrate my dev workflow with cypress. But i get a error in cypress that do not occur if i access the app from browser.

Firebase CLI version is 7.9.0 and Cypress version is "^3.8.0"

My npm scripts to load everything are below:

"start": "firebase emulators:exec --only firestore \"npm run dev:appandtest\"",
"dev:appandtest": "concurrently -n \"app,test\" -c \"bgYellow.black,bgWhite.black\" \"npm:dev:app\" \"npm:dev:test\"",
"dev:app": "webpack-dev-server --config build/webpack.dev.js",
"dev:test": "npx cypress open", 

The local server runs on port 9000 and the firebase emulator on port 8080.

After things are running, if i access the app from a normal browser everything is fine as this screen shows.

normal

enter image description here

Then i tried to run a basic cypress test with this code

    describe('The Home Page', function () {
      it('successfully loads', function () {
        cy.visit('/');
      });
    });

And i got the errors messages below:

    [2019-12-14T15:29:24.725Z]  @firebase/firestore: Firestore (6.6.2): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
    This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.

    error.ts:166 Uncaught (in promise) FirebaseError: Failed to get document because the client is offline.
        at new FirestoreError (http://localhost:9000/bundle.js:11739:149)
        at Object.next (http://localhost:9000/bundle.js:16734:8)
        at next (http://localhost:9000/bundle.js:16725:4704)
        at http://localhost:9000/bundle.js:16430:411

I took a screenshot also: buggy

enter image description here

I tried to research answers but wasn't able to find one. Thanks in advance for any help.

4
  • Unfortunately I can't offer any help, but I am running into the same issue using latest version of firebase-tools (7.12.0) and cypress (3.8.1). I can connect to the emulator without issues from my browser, but within Cypress I can't connect to my emulator. Commented Jan 13, 2020 at 22:22
  • 3
    I am also experiencing this, so I created this issue in the Cypress repo with reproduction steps: github.com/cypress-io/cypress/issues/6350 Commented Feb 6, 2020 at 18:18
  • 1
    did you try with a different server port than 9000 - we had issue with cypress connecting to a localhost:9000 play framework app; worked fine when switched to another port. think it was an issue with the developers macbook running something else on the same port Commented Feb 28, 2020 at 16:19
  • Hi @AugustinGrigorov, I didn't figure it out. After that, I tried to use jest for testing but gave up because of excess in mock code needed for firebase. No blame to the framework, I think I am just noob at testing. I am overdue to give this use case another try. Commented Jun 24, 2020 at 1:16

2 Answers 2

18

The solution to this problem, at least for now, is to enable experimentalForceLongPolling, like this:

// NOTE: do NOT put this in production.
firebase.firestore().settings({ experimentalForceLongPolling: true })

Important: this is an experimental feature and you should put it in some conditional checks with environment variables. You should not use this in production environment.

The reason for this is best described here:

The default behavior of Firestore's web SDK is to make use of WebChannel's streaming mode. The client makes what looks like an XHR, but then the server will hold the response open for 60 seconds and send as many server-initiated responses as it can during that time window.

The experimentalForLongPolling option forces the server to send only a single response per request.

And here:

That is the same workaround we are using in cypress. I think the underlying problem is that Cypress is intercepting all network traffic so it can monitor and sometimes mock. However, the webchannel protocol used by firestore has multiple replies over the same http request. The Cypress code cannot handle this and will only forward the first reply and ignore the rest.

Sign up to request clarification or add additional context in comments.

4 Comments

You may also try enabling experimentalAutoDetectLongPolling. Again, not for use in production (yet), but perhaps a little smarter than forcing long-polling always. Both of these keys worked for me, so I stayed with experimentalAutoDetectLongPolling.
In my case, using experimentalAutoDetectLongPolling did solve the initial issue but cause some tests to fail with an uncaught exception FirebaseError: Failed to get document because the client is offline.. Switching to experimentalForceLongPolling did solve this problem.
web 9: initializeFirestore(app, { experimentalForceLongPolling: true });. This saved me after 4 days of trying to find the issue :(
To avoid it going into production, I went with experimentalForceLongPolling: process.env.NODE_ENV === "development" ? true : false
4

In the v9 new API you can't rely on
provideFirebaseApp(() => initializeApp(environment.firebase)),
where environment.firebase includes { experimentalAutoDetectLongPolling: true }.

Instead you have to explicitly do this in the provideFirestore method.

 provideFirestore(() => {
      let firestore;
      if (environment.useEmulators) {
        // bug: experimentalAutoDetectLongPolling not picked up via `getFirestore`
        const app = initializeApp(environment.firebase)
        firestore = initializeFirestore(app, {
          experimentalAutoDetectLongPolling: true
        })
        connectFirestoreEmulator(firestore, 'localhost', 8080)
      } else {
        firestore = getFirestore();
      }
      return firestore;
    }),

1 Comment

how would I set this up for testing auth instead of firestore?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.