如何管理 Dialogflow / Api.ai 中的 5 秒响应超时限制?
How to manage the 5 seconds response timeout limit in Dialogflow / Api.ai?
我正在使用 Dialogflow 创建一个代理/机器人,它使用 "I need to get a letter from the HR for address proof" 等操作项来响应不同类型的用户查询。这需要机器人从公司的数据库中获取一些信息,并通过将检索到的信息填充到人力资源提供的模板信函文件中来生成文档/信函。执行此操作的逻辑已写入 python 文件中。数据库集成是使用 Webhooks 完成的。
问题在于,解释用户请求、打开数据库和检索所需信息的整个过程需要超过 5 秒,这恰好是 Dialogflow 代理的响应超时限制。我对此做了一些研究,发现我们不能增加这个限制,但我们可以通过异步调用使会话保持活动状态。我找不到提供答案的正确资源。
所以,我的问题是-
我们可以在 dialogflow 中进行异步调用吗?
如果是,那么我们如何通过json向Dailogflow代理发送异步数据?
有没有其他方法可以解决这个 5 秒响应超时限制?
提前致谢!
我刚刚查看了Actions on Google documentation and the Fulfillment documentation页,确实有5秒的超时限制。
这可能不是最好的解决方案,可能不适合您的情况,但考虑到给定的严格 5 秒 window(我们希望确保动态对话,而不会让用户冒等待的风险长)
您使用第一个意图异步开始计算,然后返回给用户并告诉他们在几秒钟内请求结果,同时计算完成。它将保存在用户的私有 space 中,此时用户将触发第二个意图,该意图将请求与此同时将被预先计算的结果,因此您可以只获取并 return他们。
您可以通过设置多个后续事件将 5 秒的 Intent 限制延长至最多 15 秒。
目前,您只能设置 3 个后续事件(最多可以延长超时 15 秒)。
以下是如何在运营中心执行此操作的示例:
function function1(agent){
//This function handles your intent fulfillment
//you can initialize your db query here.
//When data is found, store it in a separate table for quick search
//get current date
var currentTime = new Date().getTime();
while (currentTime + 4500 >= new Date().getTime()) {
/*waits for 4.5 seconds
You can check every second if data is available in the database
if not, call the next follow up event and do the
same while loop in the next follow-up event
(up to 3 follow up events)
*/
/*
if(date.found){
agent.add('your data here');//Returns response to user
}
*/
}
//add a follow-up event
agent.setFollowupEvent('customEvent1');
//add a default response (in case there's a problem with the follow-up event)
agent.add("This is function1");
}
let intentMap = new Map();
intentMap.set('Your intent name here', function1);;
agent.handleRequest(intentMap);
要了解有关自定义事件的更多信息,请访问此页面:https://dialogflow.com/docs/events/custom-events
降低代码的复杂性以使其更快;你们中的一些人正在使用微服务或纳米服务架构,例如 firebase 函数、AWS lambda 或 Kubernetes 尝试通过在函数内部而不是全局范围内初始化库来减少死启动和冷启动,
如果您有多个 API 调用,请尝试使其并行而不是一个接一个地减少。例如promise.all接近
你也可以通过数据库或者上下文来解决问题
例如用户问:我的余额是多少
Bot:我正在查看您的余额。过几秒再问
并在后台获取花费 API 的时间并将数据保存在高速数据库中,例如 MongoDB(相对于慢速网络服务 APIs ),以及在上下文菜单或数据库中标记一个标志。
几秒后用户再次询问时,检查标志是否为正从高速数据库中获取数据并提供给用户
提示:如果您使用 google 助手,您可以在从 API 获取数据完成时发送推送通知
更新:
回复评论:“你能解释一下‘在函数内部而不是全局范围内初始化库’是什么意思吗?”
例如,在 firebase 函数的情况下,它实际上是在容器化环境中执行的,当你暂时不调用该函数时,它只是简单地从内存中释放你函数的容器,当你再次调用它时在实际执行之前再次初始化容器,初始化称为冷启动,因此第一次调用花费的时间多一点,后续调用花费的时间更少,即使第一次调用的执行时间相同但函数无法执行直到容器初始化完成,容器的初始化包括所有的库和数据库连接的初始化等。这没关系,你无法在 micro/nano-service 架构中摆脱冷启动,但有时它会花费越来越多的时间并给用户带来挫败感和糟糕的体验,并且像 dialogflow first call 这样的服务每次都会失败,这不好,这里还有更多:像 firebase 这样的服务实际上为每个函数创建单独的容器,例如,如果你有多个函数,firebase 实际上将每个函数部署在一个单独的容器中,所以调用每个函数只初始化该函数的容器而不是所有其他函数容器,这里是真正的问题来了,你调用一个函数并在全局范围内初始化所有东西,不管你的函数是否使用它,大多数开发人员犯了一个错误,他们在全局范围内初始化数据库,这意味着每个函数都必须在冷启动时初始化它,但不是全部你们的函数实际上使用数据库连接,所以我们需要在每个函数的主体中分别初始化数据库,而不是在外部的功能,事实上我做的是我做了一个可重用的功能,检查数据库是否尚未连接,连接它否则什么也不做,这个检查是为了避免在每个函数调用中初始化数据库,这可能会导致执行时间增加。
稍后我会尝试添加 firebase 函数代码示例。
更新 2:
这里是代码示例
传统方式:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as _cors from 'cors';
import firestore from './../db'
import * as mongoose from "mongoose";
const defaultApp = admin.initializeApp(functions.config().firebase)
const dbURI = `mongodb://xxxxxx:xxxxxx@ds00000.mlab.com:123456/mydb`;
// const dbURI = `mongodb://localhost:27017/mydb`;
mongoose.connect(dbURI, {
useNewUrlParser: true, useUnifiedTopology: true
}).catch(e => {
console.log("mongo connection failed for reason: ", e);
})
var cors = _cors({ origin: true });// set these options appropriately According to your case,
// see document: https://www.npmjs.com/package/cors#configuration-options
// true means allow everything
// http example
export const addMessage = functions.https.onRequest((req, res) => {
const original = req.query.text;
admin.database().ref('/messages').push({ original: original }).then(snapshot => {
res.redirect(303, snapshot.ref);
});
});
export const signup = functions.https.onRequest(async (req, res) => {
... signup stuff using mongodb
res.send("user signed up");
})
//databse trigger example
export const makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite(event => {
const original = event.data.val();
console.log('Uppercasing', event.params.pushId, original);
const uppercase = original.toUpperCase();
return event.data.ref.parent.child('uppercase').set(uppercase);
});
//cors example
export const ping = functions.https.onRequest(async (req, res) => {
cors(req, res, () => {
res.send("this is a function");
})
})
在上面的代码中,你可能会注意到4个函数
- 用于在 firebase DB 中添加消息的 HTTP 触发器 addMessage
- HTTP 注册函数,使用 MongoDB
- 数据库触发器使条目大写,不使用任何数据库
- HTTP触发ping功能,不使用任何数据库
您可能还注意到两个数据库初始化,firebase 和 MongoDB
假设你在一段时间后第一次调用一个函数并且该函数是冷的,所以它会初始化这两个数据库,不仅一次而且四个函数分别初始化,假设每个数据库初始化需要 400毫秒,所以这两个需要 800 英里,所以当你调用第一个函数来添加消息时,它会初始化两个 db(800ms) 然后它会实际执行函数(比如说 150ms)所以 800ms+150ms 所以它会花费第一次大约 950 毫秒,不管它不使用 mongodb 它都会初始化它,因为初始化是在全局范围内编写的
如果您在 addMessage 函数之后立即调用注册函数,它将为 db init 执行相同的 800 毫秒,然后注册函数执行假设它需要 200 毫秒,所以总共 800+200=1000 毫秒,您可能认为 db 已经为什么要再次初始化,正如我在最初的回答中已经提到的,每个函数可能位于单独的容器中(并非总是如此,但确实如此),这意味着注册函数可能不知道 addMessage 函数中发生了什么,因此它将初始化数据库它也是容器,所以第一次调用会比后续调用花费更多时间
函数 3 是一个数据库触发器,它不使用数据库,但是当它被调用时,它接收到数据库的句柄,并使用该句柄在数据库中进行更改,但在这种情况下,函数是冷的,你在数据库中创建一个条目,它实际上像任何其他函数一样初始化函数,这意味着 800 毫秒的开销仍然是第一次,这就是大多数人讨厌数据库触发器的原因,但他们不知道它为什么会发生(在这个我想提一下,除了冷启动之外,他们的设计中还有一些问题 github 但相信我优化冷启动将解决您的问题 50%)
函数 4 只是一个 ping 函数,但它也会初始化数据库,800 毫秒的开销是白费的
现在看一下经过一些优化的以下代码:
您可能会注意到,我没有在全局范围内直接初始化数据库,而是在全局范围内注册了一个名为 initMongodb 的子例程函数,其中包含数据库初始化逻辑,因此当您调用 firebase 函数时,它不会在冷启动期间初始化数据库,但它会只需在全局范围内注册此子例程函数,这样您就可以在任何 firebase 函数中访问它,
现在,如果您观察第二个函数,即注册,您可能已经注意到我进一步有条件地进行了数据库初始化,因为如果函数没有收到正确的数据来执行注册,此时初始化数据库有什么意义我想提一下,如果数据库初始化完成一次,那么在后续调用中它实际上不会再次初始化数据库,实际上当 firebase 函数执行完成时它会销毁该 firebase 函数范围内的所有变量但它保留全局变量(直到下一个冷启动)你可能会注意到我需要 mongodb 作为变量名称 mongoose
和 firebase 作为变量名称 admin
在全局范围内并且初始化对这些变量进行了一些更改,所有这些,这就是为什么初始化逻辑是有条件的,如果数据库未初始化则初始化,否则什么都不做。
这里要注意的另一点是“不要”尝试将所有内容保留在 firebase 函数本地范围内(例如 mongoose 的导入以及 mongoose 和其他 DB 的初始化),这将使开销永久存在并且会每次调用都从头开始导入和初始化数据库,因为所有局部变量在执行完成后都会被销毁,所以它比冷启动本身更危险
最后,如果您观察功能 3 和 4,将不会进行数据库初始化,但这并不意味着冷启动和后续调用将花费相同的时间,但在此期间发生的事情很少作为将库文件从磁盘加载到内存的导入,但与数据库初始化(向互联网上的其他计算机发出 https/socket 请求)相比,这并不需要那么长的时间导入全部发生在同一台计算机上,仍然最好避免在生产中进行不必要的导入。
冷启动优化方式(推荐)
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as _cors from 'cors';
import firestore from './../db'
import * as mongoose from "mongoose";
const dbURI = `mongodb://xxxxxx:xxxxxx@ds00000.mlab.com:123456/mydb`;
// const dbURI = `mongodb://localhost:27017/mydb`;
export functions initFirebase(){
if (admin.apps.length === 0) {
console.log("initializing firebase database");
admin.initializeApp(functions.config().firebase)
}else{
console.log("firebase is already initialized");
}
}
export function initMongoDb() {
if (mongoose.connection.readyState !== mongoose.STATES.connected
&& mongoose.connection.readyState !== mongoose.STATES.connecting) {
console.log("initializing mongoose");
mongoose.connect(dbURI, {
useNewUrlParser: true, useUnifiedTopology: true
}).catch(e => {
console.log("mongo connection failed for reason: ", e);
})
} else {
console.log("mongoose already connected: ", mongoose.STATES[mongoose.connection.readyState]);
}
}
var cors = _cors({ origin: true });// set these options appropriately According to your case,
// see document: https://www.npmjs.com/package/cors#configuration-options
// true means allow everything
// http example
export const addMessage = functions.https.onRequest((req, res) => {
initFirebase()
const original = req.query.text;
admin.database().ref('/messages').push({ original: original }).then(snapshot => {
res.redirect(303, snapshot.ref);
});
});
export const signup = functions.https.onRequest(async (req, res) => {
if(req.body.name && req.body.email && req.body.password){
initMongoDb();
... signup stuff using mongodb
res.send("user signed up");
}else{
res.status(400).send("parameter missing");
}
})
//database trigger example
export const makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite(event => {
const original = event.data.val();
console.log('Uppercasing', event.params.pushId, original);
const uppercase = original.toUpperCase();
return event.data.ref.parent.child('uppercase').set(uppercase);
});
//cors example
export const function3 = functions.https.onRequest(async (req, res) => {
cors(req, res, () => {
res.send("this is a function");
})
})
Update: a ping call to function on start of mobile app or on page load in web also works well
Inzamam Malik,
Web & Chatbot developer.
malikasinger@gmail.com
我正在使用 Dialogflow 创建一个代理/机器人,它使用 "I need to get a letter from the HR for address proof" 等操作项来响应不同类型的用户查询。这需要机器人从公司的数据库中获取一些信息,并通过将检索到的信息填充到人力资源提供的模板信函文件中来生成文档/信函。执行此操作的逻辑已写入 python 文件中。数据库集成是使用 Webhooks 完成的。
问题在于,解释用户请求、打开数据库和检索所需信息的整个过程需要超过 5 秒,这恰好是 Dialogflow 代理的响应超时限制。我对此做了一些研究,发现我们不能增加这个限制,但我们可以通过异步调用使会话保持活动状态。我找不到提供答案的正确资源。
所以,我的问题是-
我们可以在 dialogflow 中进行异步调用吗?
如果是,那么我们如何通过json向Dailogflow代理发送异步数据?
有没有其他方法可以解决这个 5 秒响应超时限制?
提前致谢!
我刚刚查看了Actions on Google documentation and the Fulfillment documentation页,确实有5秒的超时限制。
这可能不是最好的解决方案,可能不适合您的情况,但考虑到给定的严格 5 秒 window(我们希望确保动态对话,而不会让用户冒等待的风险长)
您使用第一个意图异步开始计算,然后返回给用户并告诉他们在几秒钟内请求结果,同时计算完成。它将保存在用户的私有 space 中,此时用户将触发第二个意图,该意图将请求与此同时将被预先计算的结果,因此您可以只获取并 return他们。
您可以通过设置多个后续事件将 5 秒的 Intent 限制延长至最多 15 秒。 目前,您只能设置 3 个后续事件(最多可以延长超时 15 秒)。
以下是如何在运营中心执行此操作的示例:
function function1(agent){
//This function handles your intent fulfillment
//you can initialize your db query here.
//When data is found, store it in a separate table for quick search
//get current date
var currentTime = new Date().getTime();
while (currentTime + 4500 >= new Date().getTime()) {
/*waits for 4.5 seconds
You can check every second if data is available in the database
if not, call the next follow up event and do the
same while loop in the next follow-up event
(up to 3 follow up events)
*/
/*
if(date.found){
agent.add('your data here');//Returns response to user
}
*/
}
//add a follow-up event
agent.setFollowupEvent('customEvent1');
//add a default response (in case there's a problem with the follow-up event)
agent.add("This is function1");
}
let intentMap = new Map();
intentMap.set('Your intent name here', function1);;
agent.handleRequest(intentMap);
要了解有关自定义事件的更多信息,请访问此页面:https://dialogflow.com/docs/events/custom-events
降低代码的复杂性以使其更快;你们中的一些人正在使用微服务或纳米服务架构,例如 firebase 函数、AWS lambda 或 Kubernetes 尝试通过在函数内部而不是全局范围内初始化库来减少死启动和冷启动,
如果您有多个 API 调用,请尝试使其并行而不是一个接一个地减少。例如promise.all接近
你也可以通过数据库或者上下文来解决问题
例如用户问:我的余额是多少
Bot:我正在查看您的余额。过几秒再问
并在后台获取花费 API 的时间并将数据保存在高速数据库中,例如 MongoDB(相对于慢速网络服务 APIs ),以及在上下文菜单或数据库中标记一个标志。
几秒后用户再次询问时,检查标志是否为正从高速数据库中获取数据并提供给用户
提示:如果您使用 google 助手,您可以在从 API 获取数据完成时发送推送通知
更新:
回复评论:“你能解释一下‘在函数内部而不是全局范围内初始化库’是什么意思吗?”
例如,在 firebase 函数的情况下,它实际上是在容器化环境中执行的,当你暂时不调用该函数时,它只是简单地从内存中释放你函数的容器,当你再次调用它时在实际执行之前再次初始化容器,初始化称为冷启动,因此第一次调用花费的时间多一点,后续调用花费的时间更少,即使第一次调用的执行时间相同但函数无法执行直到容器初始化完成,容器的初始化包括所有的库和数据库连接的初始化等。这没关系,你无法在 micro/nano-service 架构中摆脱冷启动,但有时它会花费越来越多的时间并给用户带来挫败感和糟糕的体验,并且像 dialogflow first call 这样的服务每次都会失败,这不好,这里还有更多:像 firebase 这样的服务实际上为每个函数创建单独的容器,例如,如果你有多个函数,firebase 实际上将每个函数部署在一个单独的容器中,所以调用每个函数只初始化该函数的容器而不是所有其他函数容器,这里是真正的问题来了,你调用一个函数并在全局范围内初始化所有东西,不管你的函数是否使用它,大多数开发人员犯了一个错误,他们在全局范围内初始化数据库,这意味着每个函数都必须在冷启动时初始化它,但不是全部你们的函数实际上使用数据库连接,所以我们需要在每个函数的主体中分别初始化数据库,而不是在外部的功能,事实上我做的是我做了一个可重用的功能,检查数据库是否尚未连接,连接它否则什么也不做,这个检查是为了避免在每个函数调用中初始化数据库,这可能会导致执行时间增加。
稍后我会尝试添加 firebase 函数代码示例。
更新 2:
这里是代码示例
传统方式:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as _cors from 'cors';
import firestore from './../db'
import * as mongoose from "mongoose";
const defaultApp = admin.initializeApp(functions.config().firebase)
const dbURI = `mongodb://xxxxxx:xxxxxx@ds00000.mlab.com:123456/mydb`;
// const dbURI = `mongodb://localhost:27017/mydb`;
mongoose.connect(dbURI, {
useNewUrlParser: true, useUnifiedTopology: true
}).catch(e => {
console.log("mongo connection failed for reason: ", e);
})
var cors = _cors({ origin: true });// set these options appropriately According to your case,
// see document: https://www.npmjs.com/package/cors#configuration-options
// true means allow everything
// http example
export const addMessage = functions.https.onRequest((req, res) => {
const original = req.query.text;
admin.database().ref('/messages').push({ original: original }).then(snapshot => {
res.redirect(303, snapshot.ref);
});
});
export const signup = functions.https.onRequest(async (req, res) => {
... signup stuff using mongodb
res.send("user signed up");
})
//databse trigger example
export const makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite(event => {
const original = event.data.val();
console.log('Uppercasing', event.params.pushId, original);
const uppercase = original.toUpperCase();
return event.data.ref.parent.child('uppercase').set(uppercase);
});
//cors example
export const ping = functions.https.onRequest(async (req, res) => {
cors(req, res, () => {
res.send("this is a function");
})
})
在上面的代码中,你可能会注意到4个函数
- 用于在 firebase DB 中添加消息的 HTTP 触发器 addMessage
- HTTP 注册函数,使用 MongoDB
- 数据库触发器使条目大写,不使用任何数据库
- HTTP触发ping功能,不使用任何数据库
您可能还注意到两个数据库初始化,firebase 和 MongoDB
假设你在一段时间后第一次调用一个函数并且该函数是冷的,所以它会初始化这两个数据库,不仅一次而且四个函数分别初始化,假设每个数据库初始化需要 400毫秒,所以这两个需要 800 英里,所以当你调用第一个函数来添加消息时,它会初始化两个 db(800ms) 然后它会实际执行函数(比如说 150ms)所以 800ms+150ms 所以它会花费第一次大约 950 毫秒,不管它不使用 mongodb 它都会初始化它,因为初始化是在全局范围内编写的
如果您在 addMessage 函数之后立即调用注册函数,它将为 db init 执行相同的 800 毫秒,然后注册函数执行假设它需要 200 毫秒,所以总共 800+200=1000 毫秒,您可能认为 db 已经为什么要再次初始化,正如我在最初的回答中已经提到的,每个函数可能位于单独的容器中(并非总是如此,但确实如此),这意味着注册函数可能不知道 addMessage 函数中发生了什么,因此它将初始化数据库它也是容器,所以第一次调用会比后续调用花费更多时间
函数 3 是一个数据库触发器,它不使用数据库,但是当它被调用时,它接收到数据库的句柄,并使用该句柄在数据库中进行更改,但在这种情况下,函数是冷的,你在数据库中创建一个条目,它实际上像任何其他函数一样初始化函数,这意味着 800 毫秒的开销仍然是第一次,这就是大多数人讨厌数据库触发器的原因,但他们不知道它为什么会发生(在这个我想提一下,除了冷启动之外,他们的设计中还有一些问题 github 但相信我优化冷启动将解决您的问题 50%)
函数 4 只是一个 ping 函数,但它也会初始化数据库,800 毫秒的开销是白费的
现在看一下经过一些优化的以下代码:
您可能会注意到,我没有在全局范围内直接初始化数据库,而是在全局范围内注册了一个名为 initMongodb 的子例程函数,其中包含数据库初始化逻辑,因此当您调用 firebase 函数时,它不会在冷启动期间初始化数据库,但它会只需在全局范围内注册此子例程函数,这样您就可以在任何 firebase 函数中访问它,
现在,如果您观察第二个函数,即注册,您可能已经注意到我进一步有条件地进行了数据库初始化,因为如果函数没有收到正确的数据来执行注册,此时初始化数据库有什么意义我想提一下,如果数据库初始化完成一次,那么在后续调用中它实际上不会再次初始化数据库,实际上当 firebase 函数执行完成时它会销毁该 firebase 函数范围内的所有变量但它保留全局变量(直到下一个冷启动)你可能会注意到我需要 mongodb 作为变量名称 mongoose
和 firebase 作为变量名称 admin
在全局范围内并且初始化对这些变量进行了一些更改,所有这些,这就是为什么初始化逻辑是有条件的,如果数据库未初始化则初始化,否则什么都不做。
这里要注意的另一点是“不要”尝试将所有内容保留在 firebase 函数本地范围内(例如 mongoose 的导入以及 mongoose 和其他 DB 的初始化),这将使开销永久存在并且会每次调用都从头开始导入和初始化数据库,因为所有局部变量在执行完成后都会被销毁,所以它比冷启动本身更危险
最后,如果您观察功能 3 和 4,将不会进行数据库初始化,但这并不意味着冷启动和后续调用将花费相同的时间,但在此期间发生的事情很少作为将库文件从磁盘加载到内存的导入,但与数据库初始化(向互联网上的其他计算机发出 https/socket 请求)相比,这并不需要那么长的时间导入全部发生在同一台计算机上,仍然最好避免在生产中进行不必要的导入。
冷启动优化方式(推荐)
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as _cors from 'cors';
import firestore from './../db'
import * as mongoose from "mongoose";
const dbURI = `mongodb://xxxxxx:xxxxxx@ds00000.mlab.com:123456/mydb`;
// const dbURI = `mongodb://localhost:27017/mydb`;
export functions initFirebase(){
if (admin.apps.length === 0) {
console.log("initializing firebase database");
admin.initializeApp(functions.config().firebase)
}else{
console.log("firebase is already initialized");
}
}
export function initMongoDb() {
if (mongoose.connection.readyState !== mongoose.STATES.connected
&& mongoose.connection.readyState !== mongoose.STATES.connecting) {
console.log("initializing mongoose");
mongoose.connect(dbURI, {
useNewUrlParser: true, useUnifiedTopology: true
}).catch(e => {
console.log("mongo connection failed for reason: ", e);
})
} else {
console.log("mongoose already connected: ", mongoose.STATES[mongoose.connection.readyState]);
}
}
var cors = _cors({ origin: true });// set these options appropriately According to your case,
// see document: https://www.npmjs.com/package/cors#configuration-options
// true means allow everything
// http example
export const addMessage = functions.https.onRequest((req, res) => {
initFirebase()
const original = req.query.text;
admin.database().ref('/messages').push({ original: original }).then(snapshot => {
res.redirect(303, snapshot.ref);
});
});
export const signup = functions.https.onRequest(async (req, res) => {
if(req.body.name && req.body.email && req.body.password){
initMongoDb();
... signup stuff using mongodb
res.send("user signed up");
}else{
res.status(400).send("parameter missing");
}
})
//database trigger example
export const makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite(event => {
const original = event.data.val();
console.log('Uppercasing', event.params.pushId, original);
const uppercase = original.toUpperCase();
return event.data.ref.parent.child('uppercase').set(uppercase);
});
//cors example
export const function3 = functions.https.onRequest(async (req, res) => {
cors(req, res, () => {
res.send("this is a function");
})
})
Update: a ping call to function on start of mobile app or on page load in web also works well
Inzamam Malik,
Web & Chatbot developer.
malikasinger@gmail.com