Description
Related issues
[REQUIRED] Version info
node:18.12.1
firebase-functions:4.4.0
firebase-tools:12.4.4
firebase-admin:11.9.0
[REQUIRED] Test case
Deploy any firestore trigger functions
[REQUIRED] Steps to reproduce
I am trying to deploy a function that I have updated a hundred times before. I didn't make any code changes or library changes and also successfully deployed the same function yesterday. I started facing this issue.
I also tried the latest function and admin libraries in another project and tried deploying the same function; I still get the same error. Also tried deploying a different function entirely and still get the same error. An important note is that I haven't changed any code; it was working fine till yesterday.
The function I am deploying is a simple onUpdate trigger.
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin'
import { getFirestore, Timestamp } from 'firebase-admin/firestore'
import { firestoreRegion } from './config';
import { PromoCode } from './types';
import { adminFetch } from './utils';
import { getAuth } from 'firebase-admin/auth';
admin.initializeApp()
const db = getFirestore()
exports.addPromoPurchaseToUser = functions.region(firestoreRegion)
.firestore
.document('promoCodes/{promoCodeId}')
.onUpdate(async (change, context)=>{
const defaultDurationSeconds = 2678400 //set default duration to a month
const yearDurationSeconds = 365 * 24 * 60 * 60
const previousData = change.before.exists ? change.before.data() as PromoCode : undefined
const promoCode = change.after.exists ? change.after.data() as PromoCode : undefined
if(!promoCode){
//code doesn't exist; do nothing
return
}
const durationSeconds = promoCode?.durationSeconds ? promoCode.durationSeconds : promoCode?.duration ? promoCode.duration * 24 * 60 * 60 : defaultDurationSeconds
//only use user id if different from previous id
const userId = previousData?.user !== promoCode.user ? promoCode.user : undefined
if (!userId){
//we can consider adding delete function here in case we want to allow deleting user on a code
console.log(`Promo code ${context.params.promoCodeId} updated but userId unchanged or not set`)
return
}
const purchaseDate = Timestamp.now()
const expirationDate = new Timestamp(purchaseDate.seconds + (durationSeconds === -1 ? yearDurationSeconds : durationSeconds), 0)
console.log(`Adding promo code (${context.params.promoCodeId}) purchase to ${userId}`)
const purchaseDoc = await db.collection(`users/${userId}/purchases`).add({
purchaseDate: purchaseDate,
expirationDate: expirationDate,
durationSeconds: durationSeconds,
promoCode: context.params.promoCodeId,
//set grants if set in code
...(promoCode.grants ? { grants: promoCode.grants } : {}),
})
//fetch user data to set name and provider ids
const userRecord = await adminFetch("Fetching user data", () => {
return getAuth().getUser(userId)
})
const providerIds = userRecord?.providerData?.map(provider => provider?.providerId) ?? []
//if we have an order reference update the status of this code in the order; more fields can be added later; do with dot ref to not modify existing
if (promoCode.purchaseInfo?.orderReference) {
console.log(`Order reference existed: update promo code status for ${promoCode.purchaseInfo.orderReference.id}`)
try {
await promoCode.purchaseInfo.orderReference.update({
[`promoCodeInfo.${context.params.promoCodeId}`]: {
claimed: true,
user: userId,
userProviderIds: providerIds,
},
})
} catch (e) {
console.log(`error occurred while trying to update promo code status for order ref: ${promoCode.purchaseInfo.orderReference.path}`)
}
}
return change.after.ref.update({
userName: userRecord?.displayName ?? "",
claimedAt: purchaseDate,
userProviderIds: providerIds,
purchaseReference: purchaseDoc,
})
})
My package.json is as follows:
{
"name": "functions",
"scripts": {
"lint": "eslint \"src/**/*\"",
"build": "tsc",
"emulate": "firebase emulators:start",
"serve": "yarn build && firebase emulators:start --only functions",
"shell": "yarn build && firebase functions:shell",
"start": "yarn shell",
"deploy:test-promo": "firebase use test-promo && yarn run deployOnlyPromo",
},
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^11.9.0",
"firebase-functions": "^4.4.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.46.0",
"@typescript-eslint/parser": "^5.46.0",
"eslint": "^8.29.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-import": "^2.26.0",
"firebase-functions-test": "^0.2.0",
"typescript": "^4.9.4"
},
"private": true
}
[REQUIRED] Expected behavior
The function should have deployed successfully.
[REQUIRED] Actual behavior
i functions: updating Node.js 16 function addPromoPurchaseToUser(europe-west2)...
Build failed: > build
> tsc
node_modules/firebase-functions/lib/common/providers/database.d.ts(80,5): error TS2416: Property 'child' in type 'DataSnapshot' is not assignable to the same property in base type 'DataSnapshot'.
Type '(childPath: string) => DataSnapshot' is not assignable to type '(path: string) => DataSnapshot'.
Call signature return types 'DataSnapshot' and 'DataSnapshot' are incompatible.
The types of 'forEach' are incompatible between these types.
Type '(action: (a: DataSnapshot) => boolean | void) => boolean' is not assignable to type '(action: (a: IteratedDataSnapshot) => boolean | void) => boolean'.
Types of parameters 'action' and 'action' are incompatible.
Types of parameters 'a' and 'a' are incompatible.
Type 'DataSnapshot' is not assignable to type 'IteratedDataSnapshot'.
Types of property 'key' are incompatible.
Type 'string | null' is not assignable to type 'string'.
Type 'null' is not assignable to type 'string'.
node_modules/firebase-functions/lib/common/providers/database.d.ts(100,5): error TS2416: Property 'forEach' in type 'DataSnapshot' is not assignable to the same property in base type 'DataSnapshot'.
Type '(action: (a: DataSnapshot) => boolean | void) => boolean' is not assignable to type '(action: (a: IteratedDataSnapshot) => boolean | void) => boolean'.; Error ID: 1a2262f3
Functions deploy had errors with the following functions:
addPromoPurchaseToUser(europe-west2)
Were you able to successfully deploy your functions?
Nope as indicated above.