Search code examples
node.jsfirebasedialogflow-es

Can no longer connect Dialogflow to Firebase


My dialogflow chatbot has been unable to respond back with data from a Firebase rtdb. I have included my fulfillment code below. A few days ago, this would respond with the text "test successful" from my db, but now it returns no response available and gives the following in console:

FIREBASE WARNING: {"code":"app/invalid-credential","message":"Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Failed to parse access token response: SyntaxError: Unexpected token p in JSON at position 4"."} "

Does anyone have suggestions on how to debug this? Thanks in advance for your help!

'use strict';

const admin = require('firebase-admin');
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  databaseURL: '<DB-URL-HERE>'
});
 
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  
    
  function testintent(agent){
    return admin.database().ref().once('value').then((snapshot)=> {
      var myvalue = snapshot.test.val();
      agent.add(myvalue);
    });
  }
   
  }

  let intentMap = new Map();
  intentMap.set('Test Intent', testintent);
});

Solution

  • To fix the authentication problem of Dialogflow to Firebase, instead of using admin.credential.applicationDefault() for credentials. Define the correct service account details using admin.credential.cert(). There are two ways.

    By providing a path to a service account key JSON file:

    var serviceAccount = require("path/to/serviceAccountKey.json");
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount),
      databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
    });
    

    Or, by providing a service account object inline:

    admin.initializeApp({
      credential: admin.credential.cert({
        projectId: "<PROJECT_ID>",
        clientEmail: "foo@<PROJECT_ID>.iam.gserviceaccount.com",
        privateKey: "-----BEGIN PRIVATE KEY-----<KEY>-----END PRIVATE KEY-----\n"
      }),
      databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
    });