I have an existing webapp project hosted in Firebase, and I want to add cloud functions to it. But when I just functions with the command firebase init functions
the initial hello-world template it generates doesn't compile in TypeScript because of errors in the gRPC node module.
My folder structure:
firebase
├── .firebaserc
├── firebase.json
├── webapp // My web app. Compiles and runs well.
│ ├── package.json
│ ├── tsconfig.json
│ └── src
└── functions // Only what was autogenerated by firebase-tools.
├── .eslintrc.js
├── package.json
├── tsconfig.json
├── tsconfig.dev.json
└── src
└── index.ts
What I've Done
In my firebase
root folder I ran firebase init functions
and selected the correct project, to use TypeScript, have the default ESLint definitions, and to install the packages.
I commented out the Hello World function in functions/src/index.ts
.
I'm using the latest node 16 LTS and firebase-tools version 10.0.1.
The Error I'm Getting
When I run npm run build
in my functions
folder I get these errors.
> build
> tsc
node_modules/@grpc/grpc-js/build/src/object-stream.d.ts:11:18 - error TS2430: Interface 'IntermediateObjectWritable<T>' incorrectly extends interface 'Writable'.
The types returned by 'end(...)' are incompatible between these types.
Type 'void' is not assignable to type 'this'.
'this' could be instantiated with an arbitrary type which could be unrelated to 'void'.
11 export interface IntermediateObjectWritable<T> extends Writable {
~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/@grpc/grpc-js/build/src/server-call.d.ts:64:5 - error TS2416: Property 'end' in type 'ServerWritableStreamImpl<RequestType, ResponseType>' is not assignable to the same property in base type 'Writable'.
Type '(metadata?: any) => void' is not assignable to type '{ (cb?: (() => void) | undefined): this; (chunk: any, cb?: (() => void) | undefined): this; (chunk: any, encoding: BufferEncoding, cb?: (() => void) | undefined): this; }'.
Type 'void' is not assignable to type 'this'.
'this' could be instantiated with an arbitrary type which could be unrelated to 'void'.
64 end(metadata?: any): void;
~~~
node_modules/@grpc/grpc-js/build/src/server-call.d.ts:77:5 - error TS2416: Property 'end' in type 'ServerDuplexStreamImpl<RequestType, ResponseType>' is not assignable to the same property in base type 'Duplex'.
Type '(metadata?: any) => void' is not assignable to type '{ (cb?: (() => void) | undefined): this; (chunk: any, cb?: (() => void) | undefined): this; (chunk: any, encoding?: "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "base64url" | "latin1" | "binary" | "hex" | undefined, cb?: (() => void) | undefined): this; }'.
Type 'void' is not assignable to type 'this'.
'this' could be instantiated with an arbitrary type which could be unrelated to 'void'.
77 end(metadata?: any): void;
~~~
Found 3 errors.
What I've Tried
The only thing that works for me is using the JS firebase-functions template instead of the TS one, and it seems like that's what I will proceed with for now. Because that works great right off the bat, and I deployed it without hiccups and it works fine. But I really prefer using TS.
I definitely have a feeling I'm missing something very elementary here. Any help would be much appreciated. Thank you :)
A new version of @grpc/grpc-js
has been released that now fixes this issue with thanks to @murgatroid99. Just install v1.4.6 or later and update any dependencies as instructed in the original issue's thread.
npm install --save @grpc/grpc-js@^1.4.6
This is a known compatibility issue between @types/node
and @grpc/grpc-js
as discussed in Issue #2002.
Current solution is to downgrade your @types/node
dependency back a version.
Until it gets patched:
You add it to your package.json
file:
"@types/node": "14.18.3"