Firebase-tools: Cannot create proxy with a non-object as target or handler

Created on 17 Sep 2019  ยท  9Comments  ยท  Source: firebase/firebase-tools

[REQUIRED] Environment info


firebase-tools: 7.2.4


macOS: Mojave 10.14

[REQUIRED] Test case

const functions = require('firebase-functions')
const config = functions.config()

console.log(config)

const intialConfig = {
  DB_HOST: config.DB_HOST || 'localhost',
  DB_USER: config.DB_USER || 'root',
  DB_PASSWORD: config.DB_PASSWORD || 'root',
  DB_DATABASE: config.DB_DATABASE || 'database',
}


module.exports = intialConfig

And then initialising mysql

// Intializing SQL here
const mysql = require('mysql')
const config = require('./../../config')

const pool = mysql.createPool({
  host: config.DB_HOST,
  user: config.DB_USER,
  password: config.DB_PASSWORD,
  database: config.DB_DATABASE,
});


// Checking if it was connected sucessfully or not on server startup
pool.getConnection((err, connection) => {
  if (err) {
    console.error('error connecting: ' + err);
    return
  }
  console.log('connected as id ' + connection.threadId);
  connection.release();
  return;
});

Error

TypeError: Cannot create proxy with a non-object as target or handler
    at new Proxied (/Users/varunbindal/.nvm/versions/node/v10.15.3/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:60:22)
    at Proxied.any [as anyValue] (/Users/varunbindal/.nvm/versions/node/v10.15.3/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:475:20)
    at Object.get (/Users/varunbindal/.nvm/versions/node/v10.15.3/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:67:33)
    at Object.<anonymous> (/Users/varunbindal/Desktop/Dating App/backend-self/functions/src/config.js:8:19)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)

[REQUIRED] Steps to reproduce

Above steps and then deploying by running following command
export GOOGLE_APPLICATION_CREDENTIALS='./.keys/admin.keys.json && export dev=true && firebase emulators:start --only functions

[REQUIRED] Expected behavior

It would copy my runtime environment variable

[REQUIRED] Actual behavior

it throws the following error

TypeError: Cannot create proxy with a non-object as target or handler
    at new Proxied (/Users/varunbindal/.nvm/versions/node/v10.15.3/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:60:22)
    at Proxied.any [as anyValue] (/Users/varunbindal/.nvm/versions/node/v10.15.3/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:475:20)
    at Object.get (/Users/varunbindal/.nvm/versions/node/v10.15.3/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:67:33)
    at Object.<anonymous> (/Users/varunbindal/Desktop/Dating App/backend-self/functions/src/config.js:8:19)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
Attention functions bug

Most helpful comment

@irohitb ah I found the issue. Your config is not valid. For example you have this config:

{
    "client_url": "http://localhost:3000",
    "db_user": "root",
    "db_password": "rohit123",
    "db_host": "localhost",
    "db_database": "blendtale"
}

But you actually need to always be two-levels deep, for example this fails:

$ firebase functions:config:set db_user="root"

Error: Invalid argument, each config value must have a 2-part key (e.g. foo.bar)

So you'd want to make your config something like:

{
    "datingapp": {
        "client_url": "http://localhost:3000",
        "db_user": "root",
        "db_password": "rohit123",
        "db_host": "localhost",
        "db_database": "blendtale"
    }
}

And then in your config.js file:

const functions = require('firebase-functions')
const config = functions.config().datingapp  // THIS LINE IS DIFFERENT
const dummyConfig = { ...config }

I was able to get your app to run using this:

$ npm run serve-locally

> functions@ serve-locally /tmp/tmp.6T1mQn6kjh/DatingApp-backend/functions
> npm run admin-keys && export dev=true && firebase emulators:start


> functions@ admin-keys /tmp/tmp.6T1mQn6kjh/DatingApp-backend/functions
> export GOOGLE_APPLICATION_CREDENTIALS='./.keys/admin.keys.json'

i  Starting emulators: ["functions","database","hosting"]
โœ”  functions: Using node@10 from host.
โœ”  functions: Emulator started at http://localhost:5001
i  database: Emulator logging to database-debug.log
โœ”  database: Emulator started at http://localhost:9000
i  database: For testing set FIREBASE_DATABASE_EMULATOR_HOST=localhost:9000
i  hosting: Serving hosting files from: public
โœ”  hosting: Local server: http://localhost:5000
โœ”  hosting: Emulator started at http://localhost:5000
i  functions: Watching "/tmp/tmp.6T1mQn6kjh/DatingApp-backend/functions" for Cloud Functions...
>  [2019-09-20T18:58:15.358Z] { client_url: 'http://localhost:3000',
>    db_user: 'root',
>    db_password: 'rohit123',
>    db_host: 'localhost',
>    db_database: 'blendtale' }
โœ”  functions[status]: http function initialized (http://localhost:5001/fir-dumpster/us-central1/status).
โœ”  functions[invite]: http function initialized (http://localhost:5001/fir-dumpster/us-central1/invite).
โœ”  All emulators started, it is now safe to connect.
>  [2019-09-20T18:58:15.400Z] error connecting: Error: connect ECONNREFUSED 127.0.0.1:3306

All 9 comments

This issue does not seem to follow the issue template. Make sure you provide all the required information.

@irohitb thanks for filing this. Can you help me try and reproduce by providing a more complete test case? For example I don't see anywhere in the code you provided where you actually export any Cloud Functions?

@samtstern I am creating API by doing something similiar:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()
const glob = require("glob");
const camelCase = require("camelcase");
const mysql = require('./src/database/sql/index') // eslint-disable-line no-unused-vars
const files = glob.sync('./**/*.f.js', { cwd: __dirname, ignore: './node_modules/**'});
for(let f=0,fl=files.length; f<fl; f++){
  const file = files[f];
  const functionName = camelCase(file.slice(0, -5).split('/').join('_')); // Strip off '.f.js'
  if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === functionName) {
    exports[functionName] = require(file);
  }
}

@samtstern Also if I do something like this,

// The primary purpode of this file to help new comers with configuring environment.
const functions = require('firebase-functions')
const config = functions.config().CLIENT_URL
console.log(config)
const intialconfig = {
    DB_HOST: 'localhost',
    DB_USER: 'root',
    DB_PASSWORD: 'rohit123',
    DB_DATABASE: 'blendtale'
}

module.exports = intialconfig

it throws following error

Non-existent functions.config() value requested!
   - Path: "CLIENT_URL.Symbol(nodejs.util.inspect.custom)"
   - Learn more at https://firebase.google.com/docs/functions/local-emulator
โš   Non-existent functions.config() value requested!
   - Path: "CLIENT_URL.inspect"
   - Learn more at https://firebase.google.com/docs/functions/local-emulator
โš   Non-existent functions.config() value requested!
   - Path: "CLIENT_URL.inspect"
   - Learn more at https://firebase.google.com/docs/functions/local-emulator
โš   Non-existent functions.config() value requested!
   - Path: "CLIENT_URL.Symbol(Symbol.toStringTag)"
   - Learn more at https://firebase.google.com/docs/functions/local-emulator
โš   Non-existent functions.config() value requested!
   - Path: "CLIENT_URL.Symbol(Symbol.iterator)"
   - Learn more at https://firebase.google.com/docs/functions/local-emulator
โš   Non-existent functions.config() value requested!
   - Path: "CLIENT_URL.Symbol(Symbol.toStringTag)"
   - Learn more at https://firebase.google.com/docs/functions/local-emulator
โš   TypeError: clazz is not a constructor
    at noPrototypeIterator (internal/util/inspect.js:440:14)
    at formatRaw (internal/util/inspect.js:691:31)
    at formatValue (internal/util/inspect.js:511:10)
    at inspect (internal/util/inspect.js:191:10)
    at formatWithOptions (util.js:164:18)
    at Object.format (util.js:72:10)
    at Console.console.(anonymous function) [as log] (/Users/anilbhatia/Desktop/Dating App/backend-self/functions/node_modules/log-prefix/log-prefix.js:16:27)
    at Object.<anonymous> (/Users/anilbhatia/Desktop/Dating App/backend-self/functions/src/config.js:4:9)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
โš   We were unable to load your functions code. (see above)

Where my runtimeconfig contains

{
    "CLIENT_URL": ["http://localhost:3000"],
    "DB_USER": "root",
    "DB_PASSWORD": "rohit123",
    "DB_HOST": "localhost",
    "DB_DATABASE": "blendtale"
}

and the script to serve locally (npm run serve-locally) looks like this

    "admin-keys": "export GOOGLE_APPLICATION_CREDENTIALS='./.keys/admin.keys.json'",
    "serve-locally": "npm run admin-keys && export dev=true && firebase emulators:start",

Ok we need to find a small project that we can reproduce this with. For instance I did:

functions/index.js

const functions = require('firebase-functions');

const config = functions.config();

exports.helloWorld = functions.https.onRequest((request, response) => {
 response.json({ config });
});

.runtimeconfig.json

{
    "CLIENT_URL": ["http://localhost:3000"],
    "DB_USER": "root",
    "DB_PASSWORD": "rohit123",
    "DB_HOST": "localhost",
    "DB_DATABASE": "blendtale"
}

And when I call the function I actually get no config at all:

$ firebase emulators:exec "http http://localhost:5001/fir-dumpster/us-central1/helloWorld"
i  Starting emulators: ["functions"]
โš   Your requested "node" version "8" doesn't match your global version "10"
โœ”  functions: Emulator started at http://localhost:5001
i  functions: Watching "/tmp/tmp.ufvKsP5DBY/functions" for Cloud Functions...
โœ”  functions[helloWorld]: http function initialized (http://localhost:5001/fir-dumpster/us-central1/helloWorld).
i  Running script: http http://localhost:5001/fir-dumpster/us-central1/helloWorld
i  functions: Beginning execution of "helloWorld"
i  functions: Finished "helloWorld" in ~1s
HTTP/1.1 200 OK
connection: keep-alive
content-length: 13
content-type: application/json; charset=utf-8
date: Thu, 19 Sep 2019 23:51:11 GMT
etag: W/"d-zDbsw2W5M5X+CucfFtCloomBizI"
x-powered-by: Express

{
    "config": {}
}

โœ”  Script exited successfully (code 0)
i  Shutting down emulators.

@irohitb I apologize but running your whole project is not a good way for us to debug this issue, we need to find the smallest possible amount of code that reproduces this (which is what I was trying above).

@samtstern it just contains two endpoint and basic initialisation code (express, middleware and SQL). Can you have quick overview of it? if not, I will try to create a new separate project.

@irohitb ah I found the issue. Your config is not valid. For example you have this config:

{
    "client_url": "http://localhost:3000",
    "db_user": "root",
    "db_password": "rohit123",
    "db_host": "localhost",
    "db_database": "blendtale"
}

But you actually need to always be two-levels deep, for example this fails:

$ firebase functions:config:set db_user="root"

Error: Invalid argument, each config value must have a 2-part key (e.g. foo.bar)

So you'd want to make your config something like:

{
    "datingapp": {
        "client_url": "http://localhost:3000",
        "db_user": "root",
        "db_password": "rohit123",
        "db_host": "localhost",
        "db_database": "blendtale"
    }
}

And then in your config.js file:

const functions = require('firebase-functions')
const config = functions.config().datingapp  // THIS LINE IS DIFFERENT
const dummyConfig = { ...config }

I was able to get your app to run using this:

$ npm run serve-locally

> functions@ serve-locally /tmp/tmp.6T1mQn6kjh/DatingApp-backend/functions
> npm run admin-keys && export dev=true && firebase emulators:start


> functions@ admin-keys /tmp/tmp.6T1mQn6kjh/DatingApp-backend/functions
> export GOOGLE_APPLICATION_CREDENTIALS='./.keys/admin.keys.json'

i  Starting emulators: ["functions","database","hosting"]
โœ”  functions: Using node@10 from host.
โœ”  functions: Emulator started at http://localhost:5001
i  database: Emulator logging to database-debug.log
โœ”  database: Emulator started at http://localhost:9000
i  database: For testing set FIREBASE_DATABASE_EMULATOR_HOST=localhost:9000
i  hosting: Serving hosting files from: public
โœ”  hosting: Local server: http://localhost:5000
โœ”  hosting: Emulator started at http://localhost:5000
i  functions: Watching "/tmp/tmp.6T1mQn6kjh/DatingApp-backend/functions" for Cloud Functions...
>  [2019-09-20T18:58:15.358Z] { client_url: 'http://localhost:3000',
>    db_user: 'root',
>    db_password: 'rohit123',
>    db_host: 'localhost',
>    db_database: 'blendtale' }
โœ”  functions[status]: http function initialized (http://localhost:5001/fir-dumpster/us-central1/status).
โœ”  functions[invite]: http function initialized (http://localhost:5001/fir-dumpster/us-central1/invite).
โœ”  All emulators started, it is now safe to connect.
>  [2019-09-20T18:58:15.400Z] error connecting: Error: connect ECONNREFUSED 127.0.0.1:3306
Was this page helpful?
0 / 5 - 0 ratings