Exploring various endpoints using firestore Cloud Function

I am in the process of creating a versatile Cloud Function that can be executed on various endpoints.

This is how my original Cloud Function looks:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
const _ = require('lodash')
const { getObjectValues } = require('./helper-functions.js')
admin.initializeApp()

const json2csv = require('json2csv').parse
exports.csvJsonReport = functions.https.onRequest((request, response) => {
  const db = admin.firestore()
  const userAnswers = db.collection('/surveys/CNA/submissions')
  return (
    userAnswers
      .get()
      // eslint-disable-next-line promise/always-return
      .then(querySnapshot => {
        let surveySubmissions = []
        querySnapshot.forEach(doc => {
          const userSubmission = doc.data()
          surveySubmissions.push({
            ..._.mapValues(userSubmission.answers, getObjectValues), // format answers
            ...userSubmission.anonUser,
          })
        })

        const csv = json2csv(surveySubmissions)
        response.setHeader('Content-disposition', 'attachment; filename=cna.csv')
        response.set('Content-Type', 'text/csv')
        response.status(200).send(csv)
      })
      .catch(error => {
        console.log(error)
      })
  )
})

I am looking to enhance this function so it can work with multiple collections. Instead of targeting the CNA collection in the above function, I want it to target /surveys/:surveyId/submissions/

Here is my attempt at extending my initial Cloud Function:

const functions = require('firebase-functions')
const admin = require('firebase-admin')

const express = require('express')
const bodyParser = require('body-parser')

const _ = require('lodash')
const { getObjectValues } = require('./helper-functions.js')

admin.initializeApp(functions.config().firebase)
const db = admin.firestore()

const app = express()
const main = express()

main.use('/api/v1', app)
main.use(bodyParser.json())

exports.webApi = functions.https.onRequest(main)

app.get('surveys/:id', (request, response) => {
  const surveyId = request.query
  const userAnswers = db.collection(`/survey/${surveyId}/submissions`)
  return (
    userAnswers
      .get()
      // eslint-disable-next-line promise/always-return
      .then(querySnapshot => {
        let surveySubmissions = []
        querySnapshot.forEach(doc => {
          const userSubmission = doc.data()
          surveySubmissions.push({
            ..._.mapValues(userSubmission.answers, getObjectValues), // format answers
            ...userSubmission.anonUser,
          })
        })

        const csv = json2csv(surveySubmissions)
        response.setHeader('Content-disposition', 'attachment; filename=cna.csv')
        response.set('Content-Type', 'text/csv')
        response.status(200).send(csv)
      })
      .catch(error => {
        console.log(error)
      })
  )
})

When trying to access my endpoint:

myapp.firebaseapp.com/api/v1/surveys/CNA
The browser displays Cannot GET /api/v1/surveys/CNA.

Can someone please give me guidance on how to resolve this issue?

Answer №1

In order to create a GET endpoint for fetching a submission by its ID, you can use the code snippet below within your new Cloud Function:

app.get('surveys/:id', (request, response) => {
  const surveyId = request.params.id
  const userAnswers = db.collection(`/survey/${surveyId}/submissions`)

Please let me know if this solution works for you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Blackberry Browser's Window.Opener Feature

Does anyone else experience issues with the blackberry browser(5.0) and the javascript window.opener function? I couldn't find much help on Google regarding this problem. We have a pre-existing website that successfully populates parent window form f ...

Split up the author page description with a new line break for better readability on WordPress

I have a unique plugin that transforms the Biographical Info editor into a standard editor interface. However, I am facing an issue where line breaks/new rows created in the backend are not visible on the front end, and I'm unsure of where the problem ...

Tips for assigning a standard or custom value using JavaScript

What is the best way to automatically assign a value of 0 to my input field when the user leaves it blank? Should I use an if statement { } else { } ...

How come despite installing node 10.1.0, the system is showing the installed version as 5.6.0?

After I downloaded the NPM Windows installer from this link: https://nodejs.org/it/, I made sure to download and install the 10.1.0 version. However, when I checked my console using the command node -v, I was surprised by the following output: C:\U ...

What should be transmitted to the front-end following the successful validation of a token on the server?

My process starts with a login page and then moves to the profile page. When it comes to handling the token on the backend, I use the following code: app.use(verifyToken); function verifyToken(req, res, next) { if (req.path === '/auth/google&ap ...

Populate a Textbox Automatically using a Dropdown List

MVC 4 Changing multiple display fields based on DropDownListFor selection Having some issues trying to implement the solution mentioned above. It seems like there might be a problem with either my javascript code or the controller. JavaScript in View ...

The process of embedding one script into another script is underway

I've been struggling to optimize the loading of a responsive/mobile page, but then I came across a jQuery plugin that dynamically toggles elements based on screen width. This seemed like the perfect solution as it eliminates the need for extra HTTP re ...

"Exploring the magic of Vue.js and Three.js: A guide to seamlessly changing CSS style elements within an

I'm currently in the process of converting my Three.js project to Vue.js Within my Three.js scene, I have a 3D model with HTML points of interest attached to it. It is crucial that these points remain fixed to the model and consistently face the cam ...

What is the best way to execute fetch calls in sequence (A -> B -> C) within a React component?

I'm facing an issue with three fetch functions - a(), b(a_id), and c(b_id). The flow is such that function a returns an a_id which is then passed to function b, and b in turn returns an id passed to function c. componentDidUpdate(prevProps) { this ...

Guide on how to align h1 in the navigation bar

I've been attempting to center text on a nav bar but haven't been successful. What could I be overlooking? // include external modules import React, { Component } from "react"; import { Navbar } from "reactstrap"; import { Menu } from " ...

How can I extract the value of the first element in a dropdown using Javascript?

Imagine there is a dropdown menu with an unspecified number of options: <select id="ddlDropDown"> <option value="text1">Some text</option> <option value="text2">Some text</option> <option value="text3">Some ...

Dynamically update a directive array in Vue.js based on real-time changes

In my Vue project, I have an array defined in the data() method that is populated through a custom directive in its bind hook. Here's the code snippet: import Vue from 'vue' export default { el: '#showingFilters', name: "Filte ...

How to access global variables in node.js modules?

I'm looking to move some functionality to a new file called helpers.js. Below is the code that I have put in this file. How can I access the app variable within my method so that I can retrieve the config element called Path? Helpers = { fs: requ ...

I'm attempting to grasp the concept of AngularJS's controllerAs notation

As I attempted to experiment with controllers by writing up a few examples, I encountered an issue where the controllers would not load. An error message appeared: firstController is not a function Upon doing some research, I discovered that Angular 1.3. ...

TypeScript async function that returns a Promise using jQuery

Currently, I am facing a challenge in building an MVC controller in TypeScript as I am struggling to make my async method return a deferred promise. Here is the signature of my function: static async GetMatches(input: string, loc?: LatLng):JQueryPromise& ...

Changes on services do not affect the Angular component

Currently facing an issue with my Angular assignment where changing an element's value doesn't reflect in the browser, even though the change is logged in the console. The task involves toggling the status of a member from active to inactive and ...

What are some strategies for enhancing the efficiency of asynchronous data retrieval and caching?

I'm using this code to retrieve data asynchronously and store it in a cache for performance optimization: let cache = {} const optimizedFetch = async (url) => { if (url in cache) { // return cached result if available console.lo ...

Is it possible to modify the stroke color of the progress circle in ng-zorro?

I am working on an Angular project where I aim to create a dashboard displaying various progress circles. Depending on the progress, I need to change the color of the line. Current appearance: Desired appearance: Unfortunately, I am facing issues changi ...

Refreshing div content based on dropdown selection without reloading the page

I am currently working on implementing a dynamic dropdown feature that will update text content on a webpage without needing to refresh the entire page. The updated text will be fetched from a PHP function which receives input from the dropdown selection. ...

What is the best way to execute a function individually for every tag within a vue.js application?

I'm currently exploring the world of Vue JS and I thought it would be interesting to experiment with something new. Sometimes looking at the code first makes understanding it much easier than a lengthy explanation. Check out this code snippet on jsFi ...