Comments (11)
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.
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.
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.
@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.
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.
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.
@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.
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.
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.
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.
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)
- publish-npm failing Error: Error [ERR_REQUIRE_ESM]: require() of ES Module HOT 1
- bug: cannot read properties of undefined (reading 'includes') HOT 4
- Login after a logout happening the application fails
- Cypress e2e test fails initialization HOT 1
- feat(build): native esm support
- fix: drop support for node pre 16 HOT 2
- Support passing user claims to cy.login() ? HOT 1
- Unable to execute tests with Firebase Web SDK 9 HOT 3
- bug(commands): getAuthUser command not working HOT 4
- bug(docs): README.md setup is not clear about service account HOT 6
- Retry on 401
- bug(firestore): FieldValue.delete() not handled correctly HOT 3
- feat(callFirestore): ability to use batch writes
- bug(firestore): nested Timestamp value not persisting HOT 3
- bug: callFirestore not recognized in NextJS test HOT 1
- feat: support for component testing
- feat: switch to modular firebase sdks internally HOT 2
- bug(core): Webpack error when running cypress tests with cypress-firebase HOT 10
- callFirestore task fails when running in the CI with message "PERMISSION_DENIED: Missing or insufficient permissions." HOT 1
- Problem with Token HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cypress-firebase.