Skip to content

Build failed with error TS2416 in firebase-functions/lib/common/providers/database.d.ts(80,5) #1442

Closed
@faizanabidnaqvi

Description

@faizanabidnaqvi

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions