Using Cloud SQL Proxy from Firebase function

I'm running Google's Cloud SQL Proxy locally and it's working with locally served Firebase functions using a command like:

/cloud_sql_proxy -instances=my-project-12345:us-central1:my-instance=tcp:1433

However I don't really know how to have this work on deployed Firebase functions.

export const typeOrmConnectionOptions: ConnectionOptions = {
  name: 'primary',
  type: 'mssql',
  host: '127.0.0.1',
  port: 1433,
  username: 'sqlserver',
  password: 'my$trongPa$$word',
  database: 'TestDB',
  synchronize: true,
  logging: true,
  entities: ['lib/entity/**/*.js'],
  ...(prod && {
    extra: {
      socketPath:
        '/cloudsql/my-project-12345:us-central1:my-instance=tcp',
      credential_file: './admin-service-account-file-long-a1b2c3-hash.json'
    }
  })
};

I really am taking shots in the dark as far as passing the credential file as part of the extras object to TypeORM's connections object, however I feel like something like this must be necessary to link the service account I created following this step to database queries.

Another longshot idea I had was to use the environment variable to set the credentials using this JSON file:

process.env.GOOGLE_APPLICATION_CREDENTIALS = fs.readFileSync(
  './admin-service-account-file-long-a1b2c3-hash.json',
  'utf8'
)

No joy.

I don't think the error message is much help since I am certain the way I'm attempting this is fundamentally incorrect, but for what it's worth, the above gets the error

"Failed to connect to 127.0.0.1:1433 - connect ECONNREFUSED 127.0.0.1:1433"

How can I use the Cloud SQL Proxy to connect to a GCP database from Firebase?

Edit

I am not having luck connecting with either the socketPath property, or directly referencing the IP of the GCP RD instance with root username and password. I've seen various places that the cloud proxy is only needed in local development, and also that it is needed in production (that is where I got the idea about socketPath).

Further I have tried a test using MySql as was linked in an answer below. Formerly I had used this as a guide for SQL Server, but since that is in beta still, I thought I would give MySQL a try. Still failure, however when using that and using the services IP instead of cloud proxy, I get a timeout error.

I have also begun initializing the app with service account credentials I created from the GCP dashboard.

import { serviceAccount } from './service-account';
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(
  serviceAccount as admin.ServiceAccount
);
admin.initializeApp(adminConfig);

Answers:

Answer

cloud proxy is only needed when trying to connect from outside of google cloud network. From functions, you can directly connect using the host, port, username, and password.

I pass in those details during deployment through functions config.

firebase functions:config:set envs.db_host=$DB_HOST_PROD envs.db_user=$DB_USER_PROD envs.db_password=$DB_PASSWORD_PROD envs.db_name=$DB_NAME_PROD envs.db_use_ssl=false --project hello-world

firebase functions:config:set envs.node_env=production --project hello-world

firebase deploy --token=$FIREBASE_TOKEN --project hello-world --only functions,hosting

Refer to https://stackoverflow.com/a/55974919/515774 on how I use this to set the environment variables. I then use the environment variables to connect the database

Answer

In order to connect to a Cloud SQL instance from a Cloud Function (or Firebase function) you can use UNIX domain sockets. The documentation only shows how to do this for MySQL and PosgreSQL, not for SQL Server. It may be because it's not supported yet. However, I encourage you to give it a try.

Either way, you can also connect your Cloud Functions to a SQL Server Cloud SQL instance using a Serverles VPC Connector and the instance's private IP. Quoting the docs:

By default, Cloud Functions does not support connecting to the Cloud SQL instance using TCP. Your code should not try to access the instance using an IP address (such as 127.0.0.1 or 172.17.0.1) unless you have configured Serverless VPC Access.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.