Google Dialogflow Chatbot & Realtime Database Tutorial: Read & Write Data

I published a tutorial video on how to read from and write to the Firebase Realtime Database using snapshots and transactions. This blog post contains the code examples from the video:

Here is the index.js for the first step which is just reading from the database using a snapshot:

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');

// initialise DB connection
const admin = require('firebase-admin');
admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  databaseURL: 'ws://saveaverageage.firebaseio.com/',
});

process.env.DEBUG = 'dialogflow:debug';

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 handleAge(agent) {
    const age = agent.parameters.age;

    agent.add(`Thank you...`);

    return admin.database().ref('ageInfo').once("value").then((snapshot) => {
      var averageAge = snapshot.child("runningAverage").val();
      agent.add(`Our recorded average age is ` + averageAge);
    });
  }

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('AskAge', handleAge);
  agent.handleRequest(intentMap);
});

Next we have the index.js for the second step where I read from and write to the Realtime Database using a transaction:

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');

// initialise DB connection
const admin = require('firebase-admin');
admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  databaseURL: 'ws://saveaverageage.firebaseio.com/',
});

process.env.DEBUG = 'dialogflow:debug';

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 handleAge(agent) {
    const age = agent.parameters.age;

    agent.add(`Thank you...`);

    return admin.database().ref('ageInfo').transaction((ageInfo) => {
      if(ageInfo !== null) {
        let oldAverage = ageInfo.runningAverage;
        let oldTotalCount = ageInfo.totalCount;
        let newAverage = (oldAverage * oldTotalCount + age) / (oldTotalCount + 1);
        ageInfo.runningAverage = newAverage;
        ageInfo.totalCount+=1;
        agent.add(`Our recorded average age is ` + newAverage);
      }
      return ageInfo;
    }, function(error, isSuccess) {
      console.log('Update average age transaction success: ' + isSuccess);
    });

  }

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('AskAge', handleAge);
  agent.handleRequest(intentMap);
});

For completeness, here is also the 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": "~6.0"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "actions-on-google": "2.0.0-alpha.4",
    "firebase-admin": "^4.2.1",
    "firebase-functions": "^0.5.7",
    "dialogflow": "^0.1.0",
    "dialogflow-fulfillment": "0.3.0-beta.3"
  }
}
  • shirish sonawane

    Thanks for the details . Need help regarding passing ageinfo as a variable ** ref(‘ageInfo’) ** , such that i can accept it from the user as an input and then replace it with the ageinfo. Please guide

  • JEROME

    How can i sum up all the values in the column.Please advise how to do that .

  • adamu

    i am working on a project, i tried to get a record to compare in firebase and dialogflow but it is not working

  • adamu

    it is very helpful

  • Mariano Porcile

    Hola, soy nuevo en node.js y estoy aprendiendo.
    Tengo la siguiente función basada en tu video, que uso en un fulfillment en dialogflow, que accede a una firebase realtime.
    en “const code = agent.parameters.codigo;” recibo del dialogflow el parámetro código, que es lo que el usuario escribe.
    Con “let recortado = (code.replace(/ /g, “”)); ” le elimino los espacios en blanco.
    Y acá está mi error:
    En “let datosR = baseCodigos.recortado;” tendría que consultar en el firebase el contenido del codigo ingresado.

    Pero me toma literal, busca el contenido de “recortado” (si escribo en la firebase algo cuyo nombre sea “recortado” me devuelve su valor.

    ¿Cómo hago para que en “let datosR = baseCodigos.recortado;” me tome el contenido de recortado y no su nombre literal?

    ¡¡¡Muchas gracias!!!!

    function buscaCodigo(agent) {
    const code = agent.parameters.codigo;
    return admin.database().ref(‘baseCodigos’).transaction((baseCodigos) => {
    if(baseCodigos !== null) {

    let recortado = (code.replace(/ /g, “”)); //elimina espacios en el codigo ingresado
    let datosR = baseCodigos.recortado;

    agent.add(`Datos:` + datosR + `:`);
    }
    return baseCodigos;
    }, function(error, isSuccess) {
    console.log(‘Acceso a datos: ‘ + isSuccess);
    });
    }

  • Arghya Polley

    Thanks or sharing this video, it’s awesome.

  • Dan

    Hello, Is it possible to do more than one intent at a time? Also I am having trouble trying to implement a solution where I tell google to “start the system” and it sends a 1 on a tag to the database. I can get the parameter to be 1 but it wont send it to the database

  • Milan

    hello Mr. Fessel, i follow your all of that videos. but still i have question about dialog-flow. can we get that one particular user name, users-id, email, etc from multiple users. and save into realtime database one by one. ?

  • maria

    Hi Peter
    I love your tutorial too. I would like to ask you if you could upload a tutorial about conversation components. Card work’s fine, but browse carousel is Kopfschmerzen… :(
    Vielen Dank!

  • Billy de Fretes

    love this tutorial, i hope you add more so i can learn from you

  • Weerapat Lokatekrawee

    Is it possible to do the loop for NoSql and connect to dialogflow cause I can’t retrieve answers from realtime database?
    Here is my email: earn32578@gmail.com
    Thanks