Cannot read property 'parameters' of undefined while passing Context - Actions on Google - dialogflow-es

Currently I am trying to develop an action.
I am trying to achieve to reuse an intent. Concretely said, it means that the Assistant shall give me the first three items of a list and if I ask for more, then it should give me the next three items of the list.
I implemented the logic, which is locally working but sadly I always got the first three items from the list. Therefore i tried using a context, where I want to pass the index as a parameter and here i am running into the problem. The cloud function logs always gives me:
Cannot read property 'parameters' of undefined.
I am using dialog v2 api and the actions on Google sdk. Following link provides an example how to implement the context and I don't see a big difference there. https://developers.google.com/actions/reference/nodejsv2/overview
The code written for it looks like this:
app.intent('Default Welcome Intent', conv => {
conv.ask('Welcome.')
const lifespan = 100;
const parameters = {
index: 0,
};
conv.contexts.set('movieCtx', lifespan, parameters);
});
app.intent('New Cinema Movies Intent', async conv => {
let movieCtx = conv.contexts.get('movieCtx');
let index = movieCtx.parameters[index]
let movieRepository = new MovieRepository();
movieRepository.index = index;
await movieRepository.fetchNextTitle(3).then(function(titles) {
movieCtx.parameters[index] = movieRepository.index;
conv.ask('The 3 movies are:' + titles.join(', '))
return true;
}).catch(function(err) {
console.log(err);
return false;
});
})
My dependencies:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"actions-on-google": "^2.5.0",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.0.3",
"pg": "^7.7.1"
},
"devDependencies": {
"eslint": "^4.12.0",
"eslint-plugin-promise": "^3.6.0"
},
"private": true
}
Update:
I also tried to change the following lines but also that couldn't help me:
const parameters = {
movieIndex: 0,
};
let index = movieCtx.parameters['movieIndex']

The line
let index = movieCtx.parameters[index]
Should probably be
let index = movieCtx.parameters['index']
(You don't have index defined previous to that, so it is trying to get the reference of undefined, which isn't valid.)

I was able to find the answer!
const {dialogflow} = require('actions-on-google');
const functions = require('firebase-functions');
const MovieRepository = require('./PostgreSQL/MovieRepository');
let movieRepository = new MovieRepository();
const app = dialogflow({debug: true});
const AppContexts = {
NUMBER: 'number',
}
app.intent('Default Welcome Intent', (conv) => {
const lifespan = 10;
const parameters = {
movieIndex: 0,
};
conv.contexts.set(AppContexts.NUMBER, lifespan, parameters);
conv.ask('Welcome!')
});
app.intent('New Cinema Movies Intent', async (conv) => {
const movieCtx = conv.contexts.get(AppContexts.NUMBER);
await movieRepository.fetchNextTitle(3).then(function(titles) {
movieCtx.parameters.movieIndex = movieRepository.index;
conv.ask('The 3 movie titles are: ' + titles.join(', '));
return true;
}).catch(function(err) {
console.log(err);
return false;
});
})
app.intent('Default Fallback Intent', conv => {
conv.ask('Sorry. Can you repeat?')
})
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
As you can see you have to create the AppContext above the intents. Somhow weird but important is that you apply
NUMBER: 'number'
to the context, otherwise you get an undefined context again. And to access your parameters you just need to append your the value of your parameter like this:
movieCtx.parameters.movieIndex

Related

Function execution took 60015 ms, finished with status: 'timeout'

This code is a Google cloud function node.js script that exports a function fsdb_sch which uses the node-schedule and firebase-admin. The script sets up a scheduled job that runs every day at midnight using the node-schedule module. The job reads values from a Firebase Realtime Database at the location All_machines/Generator using firebase-admin module, and then writes the same values to new locations within the same database.
The Firebase Realtime Database is accessed with the help of a service account which is stored in a JSON file, ./******************************-7878b7ca66.json.
But When I am running this code I am getting only this error in logs nothing else this error Function execution took 60015 ms, finished with status: 'timeout'. I have increase the time till 540s but function stop after 540s i have also increase the memory but nothing work. But the same code is running fine in my local system from pas few days without any errors.
this is my code :
const schedule = require('node-schedule');
const Admin = require("firebase-admin");
const { getDatabase } = require("firebase-admin/database");
const serviceAccount = require("./*********************************-7878b7ca66.json");
Admin.initializeApp({
credential: Admin.credential.cert(serviceAccount),
databaseURL: "https://****************************.firebasedatabase.app"
});
exports.fsdb_sch = (req, res) => {
const db = Admin.database();
const Db = getDatabase();
const ref = Db.ref("All_machines/Generator");
const Ref = db.ref("All_machines/Generator")
schedule.scheduleJob('0 0 * * *',() => {
ref.once('value', (snapshot) => {
snapshot.forEach((data) => {
ref.child(data.key).child('waterY').once('value', (snapshot) => {
let childref = Ref.child(data.key).child('waterYY');
childref.set(snapshot.val());
console.log(snapshot.val());
});
ref.child(data.key).child('waterT').once('value', (snapshot) => {
let childref = Ref.child(data.key).child('waterY');
childref.set(snapshot.val());
console.log(snapshot.val());
});
ref.child(data.key).child('compY').once('value', (snapshot) => {
let childref = Ref.child(data.key).child('compYY');
childref.set(snapshot.val());
console.log(snapshot.val());
});
ref.child(data.key).child('compT').once('value', (snapshot) => {
let childref = Ref.child(data.key).child('compY');
childref.set(snapshot.val());
console.log(snapshot.val());
});
});
}, (errorObject) => {
console.log('The read failed: ' + errorObject.name);
});
});
};
This is Package.json file
{
"name": "sample-http",
"version": "0.0.1",
"description": "Cloud Function for Schedular",
"scripts": {
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "16"
},
"main": "index.js",
"dependencies": {
"firebase-admin": "^11.4.1",
"firebase-functions": "^3.14.1",
"mqtt": "^4.3.7",
"node-schedule": "^2.1.0"
},
"devDependencies": {
"firebase-functions-test": "^0.2.0"
},
"private": true
}
And this is the folder structure
Logs:
Cloud functions have timeout, you should not use cloud functions for long running tasks.
You can use this guide to trigger your function using cloud scheduler instead.
scheduler will publish to a topic(just empty data) based on your cron expression
topic will trigger your cloud function, and execute required script.

Webhook stopped working. Has there been a deprication or requirements change?

I'm revisiting a Dialogflow Essentials app set up a few years ago that suddenly stopped working at the webhook calls. The URLs that respond to the webhooks are still functioning perfectly. Has there been a change in webhook requirements or a Google deprication that might account for this?
The "help" and "goodbye" functions internal to the app are still working, but when a webhook call is executed we get a reply that the app "isn't responding right now. Please try again soon." and the app leaves the conversation.
The relevant code is NodeJS version 8 (which should still be functional, though depricated) and is applied using the Inline Editor within Dialogflow. Here are the functions:
function get_keywords(agent) {
const keywords = agent.parameters.keywords;
const site_id = agent.parameters.site_id;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/StorySummary_API.cfm?SiteID=${site_id}&Keywords=${keywords}`)
.then((result) => {
console.log(result.data);
if (response.statusCode != 200) {
agent.add(`Error. Could not connect to news server.`);
} else {
if (result.data.storyFound.length < 1) {
agent.add(result.data.speech);
} else {
if (result.data.storyPhotoURL.length > 1) {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
imageUrl: result.data.storyPhotoURL,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
} else {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
}
}
}
});
}
function get_rss_feed_id(agent) {
const rss_feed_id = agent.parameters.rss_feed_id;
const site_id = agent.parameters.site_id;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/NewsHeadlines_API.cfm?SiteID=${site_id}&RSSFeedID=${rss_feed_id}`)
.then((result) => {
agent.add(result.data.speech);
});
}
Here are versions of the URLs called by the webhooks (with real/live parameter values):
Headlines Group
Specific news item
I'm not seeing any activity in logs relating to these calls, and I see no billing/credit-card issues.
Any thoughts on why this is suddenly failing would be greatly appreciated!
I cannot create a NodeJS 8 environment since it is already deprecated. Instead, I tested your code in NodeJS 10 and it works fine for me.
For testing, I used an intent that is triggered with "Test" and I hard coded values for keywords,site_id,rss_feed_id. And it returned the expected result from the code.
Code used for testing:
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card} = require('dialogflow-fulfillment');
const axios = require('axios');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function yourFunctionHandler(agent) {
const keywords = 'investigation';
const site_id = 15;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/StorySummary_API.cfm?SiteID=${site_id}&Keywords=${keywords}`)
.then((result) => {
console.log(result.data);
if (response.statusCode != 200) {
agent.add(`Error. Could not connect to news server.`);
} else {
if (result.data.storyFound.length < 1) {
agent.add(result.data.speech);
} else {
if (result.data.storyPhotoURL.length > 1) {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
imageUrl: result.data.storyPhotoURL,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
} else {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
}
}
}
});
}
function get_rss_feed_id(agent) {
const rss_feed_id = 1;
const site_id = 15;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/NewsHeadlines_API.cfm?SiteID=${site_id}&RSSFeedID=${rss_feed_id}`)
.then((result) => {
agent.add(result.data.speech);
});
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('test intent', yourFunctionHandler);
//intentMap.set('test intent', get_rss_feed_id);
agent.handleRequest(intentMap);
});
Package.json:
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"firebase-functions": "^2.0.2",
"firebase-admin": "^5.13.1",
"googleapis": "^27.0.0",
"actions-on-google": "2.2.0",
"dialogflow-fulfillment": "0.6.1",
"axios": "0.21.1"
}
}
Test using get_keywords():
Test using get_rss_feed_id():
What I could suggest is to upgrade to NodeJS 10 to ensure that the function is on a supported version of Node.js. See migration guide.

Agent unable to print all results received from Axion library request in Dialogflow

I'm trying to print all results received from the following request (this code not working):
function searchForProducts(agent) {
// category_name = 'Cooking' for example
const category_name = agent.parameters.category_name;
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
let Categories = res.data[0];
if (Categories) {
for(var i=0;i<res.data.length;i++){
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${Categories.ProductID}\n\n${Categories.Name}`);
}
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
The problem I'm facing is the agent can only print on result through the following code (this record working but return only one URL):
function searchForProducts(agent) {
const category_name = agent.parameters.category_name;
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
let Categories = res.data[0];
if (Categories) {
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${Categories.ProductID}\n\n${Categories.Name}`);
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
What I'm doing wrong?
============ After Applying Proposed Solution ================
Hello, since yesterday I'm testing but with no luck to get the exact problem. Here what I did:
I created new Intent which will trigger your code once "Test" received.
I have test the code using different ways, and here the result:
Category_Name = “Cooking”:
- Dialogflow Agent Test: Worked (https://imgur.com/sov6Th5).
- Web Agent Test: Not Worked (https://imgur.com/15qxgdR).
- Dialogflow Web Messenger: Worked (https://imgur.com/5ajzd2j).
- Twilio: Not Worked (https://imgur.com/fsrYtDG) and error message was (https://imgur.com/jP6TRbZ).
But, when I changed the Category_Name = “Small%20Appliances”:
- Dialogflow Agent Test: Worked (https://imgur.com/undefined).
- Web Agent Test: Worked (https://imgur.com/undefined).
- Dialogflow Web Messenger: Worked (https://imgur.com/rCn8ksT).
- Twilio: Worked (https://imgur.com/kfXGqTf).
Here a link for web test (I will keep Category_name=’Cooking’) so you can see the result:
https://bot.dialogflow.com/004077c2-d426-472c-89f0-4997e2955d59
What do you think?
Using your code above I was able to loop through agent.add() and got the results. I used test as user input that matches intent "test intent".
Here is a snippet of the 29 similar outputs of your code provided:
Here is the full code:
index.js
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const axios = require('axios');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function yourFunctionHandler(agent) {
const category_name = 'Cooking';
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
console.log(res.data);
let Categories = res.data[0];
if (Categories) {
for(var i=0;i<res.data.length;i++){
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${Categories.ProductID}\n\n${Categories.Name}`);
}
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('test intent', yourFunctionHandler);
agent.handleRequest(intentMap);
});
package.json
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"firebase-functions": "^2.0.2",
"firebase-admin": "^5.13.1",
"googleapis": "^27.0.0",
"actions-on-google": "2.2.0",
"dialogflow-fulfillment": "0.6.1",
"axios": "0.21.1"
}
}
Just a suggestion, since your objective is to show all products under a certain "category" you might want to loop through the whole res.data. In this example I just used category_name = 'Cooking' and printed all products that is under the specified category.
function yourFunctionHandler(agent) {
const category_name = 'Cooking';
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
let Categories = res.data;
if (Categories) {
for (const product of Categories ){
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${product.ProductID}\n\n${product.Name}`);
}
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
This will result to:

Dialogflow #vitalets/google-translate-api Translation not working

I am using firebase and my translation doesn't working :(
I am not getting any response from it but other functions are working fine
here is my index.js
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const translate = require('#vitalets/google-translate-api');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function addTwoNo(agent) {
const sno = agent.parameters['sno'];
const fno = agent.parameters['fno'];
var sum = sno + fno ;
agent.add(`Sum is `+sum)
}
function tratext(agent) {
const text = agent.parameters['text'];
const lto = agent.parameters['lang-to'];
const lfrom = agent.parameters['lang-from'];
const ltoLen = lto.length > 0;
const lfromLen = lfrom.length > 0;
if(ltoLen){
translate(agent.text, {to: lto}).then(res => {
agent.add(res.text);
}).catch(err => {
console.error(err);
});
} else {
translate(agent.text, {to: 'en'}).then(res => {
agent.add(res.text);
}).catch(err => {
console.error(err);
});
}
translate(agent, {to: 'en'}).then(res => {
console.log(res.text);
//=> I speak English
console.log(res.from.language.iso);
//=> nl
}).catch(err => {
console.error(err);
});
}
// // Uncomment and edit to make your own intent handler
// // uncomment `intentMap.set('your intent name here', yourFunctionHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function yourFunctionHandler(agent) {
// agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);
// agent.add(new Card({
// title: `Title: this is a card title`,
// imageUrl: 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
// text: `This is the body text of a card. You can even use line\n breaks and emoji! 💁`,
// buttonText: 'This is a button',
// buttonUrl: 'https://assistant.google.com/'
// })
// );
// agent.add(new Suggestion(`Quick Reply`));
// agent.add(new Suggestion(`Suggestion`));
// agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});
// }
// // Uncomment and edit to make your own Google Assistant intent handler
// // uncomment `intentMap.set('your intent name here', googleAssistantHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function googleAssistantHandler(agent) {
// let conv = agent.conv(); // Get Actions on Google library conv instance
// conv.ask('Hello from the Actions on Google client library!') // Use Actions on Google library
// agent.add(conv); // Add Actions on Google library responses to your agent's response
// }
// // See https://github.com/dialogflow/fulfillment-actions-library-nodejs
// // for a complete Dialogflow fulfillment library Actions on Google client library v2 integration sample
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('addTwoNo', addTwoNo);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('tratext',tratext)
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
and here is my package.json
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^2.2.0",
"firebase-admin": "^5.13.1",
"firebase-functions": "^2.0.2",
"dialogflow": "^0.6.0",
"dialogflow-fulfillment": "^0.5.0",
"#vitalets/google-translate-api": "^4.0.0"
}
}
I am using pay to go firebase
i tested using addTwoNo function and it is working but translate doesn't
I hope I get some help
It seems that, under your tratext function(agent), you are translating the "agent" instead of the "agent.text". You could try as following:
translate(agent.text, {to: 'en'}).then(res => {
console.log(res.text);
//=> I speak English
console.log(res.from.language.iso);
//=> nl
}).catch(err => {
console.error(err);
});
Also, in order to discard any issue with the translate api authentication, you could debug the translate api by translating a dummy text. I suggest you to try using this code snippet and verify the logs generated:
translate("Hola mundo", {to: 'en'}).then(res => {
console.log(res);
}).catch(err => {
console.error(err);
});
Finally, I found a github repository where a user shared a code snippet for translating text using the dialogflow fulfillment under NodeJS, that you may use for reference.

Node, firebase functions Property 'map' does not exist on type 'Promise<QuerySnapshot>

Firstly that does not helps me: property map does not exist and importing 'rxjs' does nork either
just testing using typescript with my functions and using "async" and "await" keywords for some reason I'm getting error when trying to use map here is my code(btw if the way I retriving data from firestore using "await" is incorrect I would be very greatfull if someone correct me) -could not find alot of examples that uses typescript/functions/firestore):
import * as functions from 'firebase-functions';
import * as admin from "firebase-admin";
admin.initializeApp(functions.config().firebase);
let db = admin.firestore();
export const helloWorld = functions.https.onRequest(
async (request, response) => {
try {
let t = await getEmployees()
response.send("yes");
} catch (e) {
response.send('no')
}
});
async function getEmployees(): Promise<any> {
try {
const f = await db.collection('companies').get().map(value => {
let id = value.id
return id;
})
} catch (e) {
return e;
}
}
typescript Version 2.8.3
package.json:
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^5.12.0",
"firebase-functions": "^1.0.1"
},
"devDependencies": {
"tslint": "^5.8.0",
"typescript": "2.8.3"
},
"private": true
}
await will be applied over the result of map, you are essentially calling :
const f = await (db.collection('companies').get().map(...))
You want to call map on the result of awaiting get, and you should add parenthesis to tell the compiler this is what you want tot do. Also you are probably looking for the docs property on the snapshot (which returns the results of the query)
const f = (await db.collection('companies').get()).docs.map(...)

Resources