Code Monkey home page Code Monkey logo

Comments (11)

prescottprue avatar prescottprue commented on June 12, 2024 1

Are you getting logs from cypress-firebase in the terminal where you are running the test command? They should appear showing which emulator ports are being connected to - that is based on FIREBASE_DATABASE_EMULATOR_HOST and FIRESTORE_EMULATOR_HOST environment variables that are used internally to initialize an app instance to be used by the tasks when interacting with the database

from cypress-firebase.

dutzi avatar dutzi commented on June 12, 2024 1

I'm also getting the same error when calling cy.callFirestore('add', 'some_path', { some: 'value' }); I get:

cy.task('callFirestore') failed with the following error:

> Channel credentials must be a ChannelCredentials object

I'm pretty sure it's not an issue with serviceAccount.json since I am able to log in and when I try working against production Firestore everything works.

from cypress-firebase.

brookslybrand avatar brookslybrand commented on June 12, 2024 1

I strugged with the Channel credentials must be a ChannelCredentials object error for 2 days last week, and finally stumbled across the solution:
npm i -D google-gax

Here is where I found it:
googleapis/nodejs-firestore#998 (comment)
https://stackoverflow.com/questions/61605189/firebase-emulator-error-channel-credentials-must-be-a-channelcredentials-object

It seems like it's an issue with the packages stepping on each other when you have both firebase and firebase-admin installed, which in this case is pretty necessary. I really hope this helps any and all still dealing with this problem. Let me know if it doesn't work though.

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024 1

@brookslybrand Thank you so much for posting! I'm thinking that this should be added to the docs while they are working on a fix.

I've also seen issues like this solved in the past by installing @firebase/app manually as well - wonder if there is any overlap?

from cypress-firebase.

gregfenton avatar gregfenton commented on June 12, 2024

ARGGHHH!!
In trying to debug the issue over a period of time, I had renamed that variable CYPRESS_FIRESTORE_EMULATOR_HOST so that it would show up in Cypress.env(). Once I got some pieces working, I failed to undo that change 😱

Millions of thanks yous!! I will publish a PR with a doc enhancement outlining this excellent piece of information!

from cypress-firebase.

gregfenton avatar gregfenton commented on June 12, 2024

Okay, hopefully a last volley on this topic.

I am properly getting

cypress-firebase: Using Firestore emulator with settings: { servicePath: 'localhost', port: 5002 }

when running cypress open (woohoo!)

Running my super-simple spec via Cypress I get, the first command is cy.login() and I am getting:
Channel credentials must be a ChannelCredentials object

I dug into grpc, threw in a console.log() and got:

GRPC(js) :: "credentials" is:
InsecureChannelCredentialsImpl {
  callCredentials: EmptyCallCredentials {}
}

Thoughts on what to try next?

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

@gregfenton Do you have your service account saved to ./serviceAccount.json? A service account is needed for auth actions since there isn't currently emulation for auth. With that file in place cypress-firebase will use that as a credential by default. Otherwise you can set the GOOGLE_APPLICATION_CREDENTIALS as described in the google cloud docs

from cypress-firebase.

gregfenton avatar gregfenton commented on June 12, 2024

I do have ./serviceAccount.json. The credentials are being loaded.

I put two console.log()s into cypress-firebase's tasks.js in callFirestore(). I broke up the line from being chained so that it is now:

if (action === 'get') {
  try {
    let x = await firebase_utils_1.slashPathToFirestoreRef(adminInstance.firestore(), actionPath, options);
        console.log("CYPRESS-FIREBASE -- callFirestore() -- x is:", x);
        console.log("CYPRESS-FIREBASE -- callFirestore() -- x._firestore._settings.credentials is:", x._firestore._settings.credentials);
        console.log("CYPRESS-FIREBASE -- callFirestore() -- got x.get", x.get);
    let snap = await x.get();
        console.log("GLF -- CYPRESS-FIREBASE -- callFirestore() -- have snap", snap);

and the resulting log got:

CYPRESS-FIREBASE -- callFirestore() -- x is: CollectionReference {
  _firestore: Firestore {
    _settings: {
      credentials: [Object],
      projectId: 'MY_PROJECT_ID',
      firebaseVersion: '8.12.1',
      libName: 'gccl',
      libVersion: '3.8.0 fire/8.12.1',
      ssl: false,
      customHeaders: [Object],
      servicePath: 'localhost',
      port: 5002
    },
    _settingsFrozen: true,
    _serializer: Serializer { createReference: [Function], allowUndefined: false },
    _projectId: 'MY_PROJECT_ID',
    registeredListenersCount: 0,
    _lastSuccessfulRequest: 0,
    _backoffSettings: { initialDelayMs: 100, maxDelayMs: 60000, backoffFactor: 1.3 },
    _preferTransactions: false,
    _clientPool: ClientPool {
      concurrentOperationLimit: 100,
      maxIdleClients: 1,
      clientFactory: [Function],
      clientDestructor: [Function],
      activeClients: Map {},
      terminated: false,
      terminateDeferred: [Deferred]
    }
  },
  _queryOptions: QueryOptions {
    parentPath: ResourcePath { segments: [] },
    collectionId: 'users',
    converter: {
      toFirestore: [Function: toFirestore],
      fromFirestore: [Function: fromFirestore]
    },
    allDescendants: false,
    fieldFilters: [],
    fieldOrders: [],
    startAt: undefined,
    endAt: undefined,
    limit: undefined,
    limitType: undefined,
    offset: undefined,
    projection: undefined
  },
  _serializer: Serializer { createReference: [Function], allowUndefined: false },
  _allowUndefined: false
}

CYPRESS-FIREBASE -- callFirestore() -- x._firestore._settings.credentials is: {
  private_key: '-----BEGIN PRIVATE KEY-----\n' +
    ' ...  BIG_PRIVATE_KEY FROM SERVICEACCOUNT.JSON ... \n' +
    '-----END PRIVATE KEY-----\n',
  client_email: 'firebase-adminsdk-SOMEVALS@MY_PROJECT_ID.iam.gserviceaccount.com'
}

The third console.log() line does not get output because x.get() throws an exception that gets sent to handleError that outputs:

cypress-firebase: Error with Firestore "get" at path "users" : TypeError: Channel credentials must be a ChannelCredentials object
    at new ChannelImplementation (/Users/MERP/work/MY_APP/node_modules/google-gax/node_modules/@grpc/grpc-js/src/channel.ts:153:6)
    at new Client (/Users/MERP/work/MY_APP/node_modules/google-gax/node_modules/@grpc/grpc-js/src/client.ts:152:4)
    at new ServiceClientImpl (/Users/MERP/work/MY_APP/node_modules/google-gax/node_modules/@grpc/grpc-js/build/src/make-client.js:50:5)
    at GrpcClient.createStub (/Users/MERP/work/MY_APP/node_modules/google-gax/src/grpc.ts:296:4)

from cypress-firebase.

gregfenton avatar gregfenton commented on June 12, 2024

Alright, now I am completely stumped.

This looks like some very weird "bug" (??) in grpc and/or my node/javascript environment. One that I simply do not understand.

I am hacking the files in my node_modules and running everything locally. The error I get running against the local emulator/with a serviceAccount comes from lines 149-153 of channel.ts. At that line, it is doing an instanceof to determine if the credentials are of type ChannelCredentials.

When running against the emulator/serviceAccount, the provided credentials object (as seen from console.log() output) is:

credentials are InsecureChannelCredentialsImpl {
  callCredentials: EmptyCallCredentials {}
}

a-a-a-a-n-n-n-d-d-d InsecureChannelCredentialsImpl is defined in channel-credentials.ts as:

class InsecureChannelCredentialsImpl extends ChannelCredentials {

So... InsecureChannelCredentialsImpl is not considered an instance of ChannelCredentials, though the former extends the latter.

More console.log()ing shows that:

-- @GRPC(channel.js) -- ChannelImplementation.constructor() -- credentials prototypes:
    credentials.__proto__ InsecureChannelCredentialsImpl {}
    credentials.__proto__.__proto__ ChannelCredentials {}
    credentials.__proto__.__proto__.__proto__ {}
-- @GRPC(channel.js) -- ChannelImplementation.constructor() -- channel_credentials_1.ChannelCredentials prototypes:
    channel_credentials_1.ChannelCredentials.__proto__ [Function]
    channel_credentials_1.ChannelCredentials.__proto__ {}

Yet when run without specifying FIRESTORE_EMULATOR_HOST, I get:

-- @GRPC(channel.js) -- ChannelImplementation.constructor() -- credentials prototypes:
    credentials.__proto__ ComposedChannelCredentialsImpl {}
    credentials.__proto__.__proto__ ChannelCredentials {}
    credentials.__proto__.__proto__.__proto__ {}
-- @GRPC(channel.js) -- ChannelImplementation.constructor() -- channel_credentials_1.ChannelCredentials prototypes:
    channel_credentials_1.ChannelCredentials.__proto__ [Function]
    channel_credentials_1.ChannelCredentials.__proto__.__proto__ {}

(I'm not sure how to inspect into the [Function] appropriately).

BTW: ComposedChannelCredentialsImpl is

class ComposedChannelCredentialsImpl extends ChannelCredentials {

The test of ComposedChannelCredentialsImpl instanceof ChannelCredentials passes, whereas for InsecureChannelCredentialsImpl it fails. THIS IS THE WEIRDITY.

NOW, if I comment out the test for instanceof on line 149, then EVERYTHING RUNS FINE. That is: cy.callFirestore("get", "users") returns the results from the emulator's Firestore db. And if I run the exact same setup without specifying FIRESTORE_EMULATOR_HOST then the code runs fine and lists the users that are in my Firestore database via the Firebase Console (i.e. in the cloud).

Meh.

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

Could you all list the version of node you are using? This seems to be something internal to Firestore, but not sure what could be causing it. Still trying to replicate on my end, do either of you have a repo you can share?

Its weird since there are a number of placing I'm currently using this in tests including multiple tests for fireadmin.io

from cypress-firebase.

prescottprue avatar prescottprue commented on June 12, 2024

I just tried to replicate this with most up to date versions and didn't experience it. Going to close for now, but if anyone else experiences this again, please reach out - we will add a note to the docs if so

from cypress-firebase.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.