Firebase database triggers and Rest API in same project?

Viewed 304

I have a Firebase cloud function project that I recently updated all the functions.https.onRequest to run through Express to create a REST API service. The APIs work fine. But when I try and deploy the project, none of the previous Firebase database triggers are deployed anymore (Example: CalculateMyStats trigger worked fine, but was removed from my cloud functions list) . Only the rest function is deployed now. Is it possible to have Rest API's and triggers in the same project?

index.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
import * as http from './http';

import { AddLocationIOBookMarks, DistrubuteNotificationData, NewUserEmail } from './users/usersFuncModules';

import { AutoCheckoutCron } from './locations/locationsFuncModule';
import { CalculateMyStats } from './rating/ratingFuncModule';
import { FIREBASE_CONFIG } from './config/firebaseConfig';
import { LocationsUserCount } from './pushNotifications/pushFuncModule';

export { AddLocationIOBookMarks, DistrubuteNotificationData, NewUserEmail };

export { AutoCheckoutCron };

export { CalculateMyStats };
export { LocationsUserCount };

admin.initializeApp({
  credential: admin.credential.cert({
    projectId: FIREBASE_CONFIG.project_id,
    clientEmail: FIREBASE_CONFIG.client_email,
    privateKey: FIREBASE_CONFIG.private_key
  }),
  databaseURL: FIREBASE_CONFIG.databaseURL
});

admin.firestore().settings({ timestampsInSnapshots: true });

exports.rest = functions.https.onRequest(http.endpoint);

ratingFuncModule.ts

import * as express from 'express';
import * as functions from 'firebase-functions';
import * as http from '../http';
import * as myStatsModule from './calculateMystats';
import * as ratingModule from './rateUser';

import { fsConst } from '../firestoreConst';

const rateRoute = express.Router();
const cors = require('cors');
const corsOptions = http.corsOptions;


export const CalculateMyStats = functions.firestore.document(`${fsConst.USERRATINGS}/{doc-id}`).onWrite((change, context) => {
  const ratedUser = change.after.data();
  return myStatsModule.roundAllMyStats(ratedUser.userId).catch(error => {
    console.error(new Error(error), `| Method: CalculateMyStats`);
  });
});

rateRoute.get('/rate/updateRating', cors(corsOptions), (req, res) => {
  const currentUserId = req.query.currentUserId;
  const toBeRatedUserId = req.query.toBeRatedUserId;
  const rateDocId = req.query.rateDocId;
  const rateFormValues = req.query.rateFormValues;


  ratingModule
    .rateCurrentUser(currentUserId, toBeRatedUserId, rateDocId, rateFormValues)
    .then(data => {
      if (rateDocId !== 'undefined') {
        res.send(JSON.stringify(rateDocId));
      } else {

        res.send(JSON.stringify(data));
      }
    })
    .catch(error => {
      console.error(new Error(error), `| Method: updateUserRating`);
    });
});

// Export all routes for rating related http request
module.exports = rateRoute;

firebase.json

{
  "functions": {
    "predeploy": [
      "npm --prefix $RESOURCE_DIR run lint",
      "npm --prefix $RESOURCE_DIR run build"
    ],
    "source": "functions"
  },
  "hosting": {
    "public": "public",
    "rewrites": [{
      "source": "/api/v1/**",
      "function": "rest"
    }],
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
  }
}

And when I deploy:

firebase deploy --only functions
1 Answers

You have to export all your trigger functions alongside your exports.rest in index.ts like so:

import { CalculateMyStats } from './rating/ratingFuncModule';

exports.rest = functions.https.onRequest(http.endpoint); // your existing export
exports.calculateMyStats = CalculateMyStats // trigger function export
Related