Cannot deploy Cloud function because of "FlutterFlow has insufficient permissions"

Custom Code

The error message is Error: FlutterFlow has insufficient permissions. Make sure to re-watch the "Adding Firebase" tutorial and follow all necessary steps.

My FlutterFlow app was running, but I want to migrate form using GCP Cloud Functions via API calls to FlutterFlow Cloud Functions due to CORS shenanigans. Sometimes the function worked, sometimes don't and I thought that "native" FF Cloud Function has a better chance hopefully to avoid that.

First I converted my Python GCP Cloud Function to a v2 JavaScript Cloud Function, then I realized FF only does v1, so I migrated again, and tested the code on GCP. I went through the tutorial, I use FireStore and it worked as well. The mailto:[email protected] has the permissions listed.

When I started to edit FF Cloud Functions the package.json was empty, so digging in some forum posts I crafted the advised one:

{
  "name": "functions",
  "description": "Firebase Custom Cloud Functions",
  "engines":{
    "node": "18"
  },
  "main": "index.js",
  "dependencies": {
    "firebase-admin": "^12.1.0",
    "firebase-functions": "^5.0.1",
    "@google-cloud/dialogflow-cx": "^4.6.0",
    "@google-cloud/storage": "^7.11.0"
  },
  "private": true
}

The function might only have a diversion because it's using https.onRequest instead of https.onCall because the req and res parameters match the v2 functions and I'm trying to use some CORS treatment and also JSON payload return.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
// To avoid deployment errors, do not call admin.initializeApp() in your code

const {Storage} = require('@google-cloud/storage');
const {SessionsClient} = require('@google-cloud/dialogflow-cx').v3beta1;

credentials = {
  "type": "service_account",
  "project_id": "duet-ai-roadshow-415022",
  "private_key_id": "*",
  "private_key": "-----BEGIN PRIVATE KEY-----*\n-----END PRIVATE KEY-----\n",
  "client_email": "*.iam.gserviceaccount.com",
  "client_id": "*",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/goog-sc-aiml-image-process-847%40duet-ai-roadshow-415022.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}

/**
 * Example for regional endpoint:
 *   const location = 'us-central1'
 *   const client = new SessionsClient({apiEndpoint: 'us-central1-dialogflow.googleapis.com', credentials: credentials})
 */
const client = new SessionsClient({apiEndpoint: 'us-central1-dialogflow.googleapis.com'});

// onCall(async (data, context)
exports.getTrivia = functions.region('uscentral-1').runWith({memory: '128MB'}).https.onRequest(async (req, res) => {
  // CORS handling
  res.set('Access-Control-Allow-Origin', "*");
  res.set('Access-Control-Allow-Methods', 'GET, POST');
  res.setHeader(
      "Access-Control-Allow-Headers",
      "X-Requested-With,content-type"
  );

  let token = req.body.token || req.query.token;
  let slToken = process.env.SL_TOKEN || "***";
  if (token !== slToken) {
    res.status(401).send("Invalid token");
    return;
  }

  let projectId = process.env.PROJECT_ID || "duet-ai-roadshow-415022";

  // GOOGLE_APPLICATION_CREDENTIALS ???
  // https://stackoverflow.com/questions/52635632/setting-google-application-credentials-in-current-shell-session-via-node-js
  const storage = new Storage({
    projectId: projectId,
    credentials
  });

  let locationId = req.body.location_id || req.query.location_id || process.env.LOCATION_ID || 'us-central1';
  let agentId = req.body.agent_id || req.query.agent_id || process.env.AGENT_ID;
  let languageCode = req.body.language_code || req.query.language_code || process.env.LANGUAGE_CODE || 'en'
  let sessionId = req.body.session_id || req.query.session_id;
  const sessionPath = client.projectLocationAgentSessionPath(
    projectId,
    locationId,
    agentId,
    sessionId
  );

  let query = req.body.query || req.query.query || "";

  const request = {
    session: sessionPath,
    queryInput: {
      text: {
        text: query,
      },
      languageCode,
    },
  };
  const [response] = await client.detectIntent(request);
  let fullResponse = "";
  for (const message of response.queryResult.responseMessages) {
    if (message.text) {
      fullResponse += message.text.text;
    }
  }

  res.json(JSON.parse(fullResponse));
});

It's another issue that with native GCP functions I'm able to perform the service account authorization via a secret JSON file I can add and refer to. I cannot add another JSON in FF to do that so I'm trying to work around that by ugly way hard coding some secrets.

But that doesn't even matter since I cannot even deploy the function.

What have you tried so far?

I tried adjusting the package.json, removed some stuff. The error message sometimes changed to "Unknown error, contact FlutterFlow...". I tried adjusting node version in that file, removing fields one-by-one except the dependencies.

I double checked the user has the right privileges. Tested part of the code in native GCP function. Not sure what else to do.

Did you check FlutterFlow's Documentation for this topic?
Yes
1
3 replies