javascript tutorial ¿Cómo conectar Google Cloud SQL desde Cloud Functions?




google cloud functions example (5)

Estoy tratando de usar Cloud Functions for Firebase para construir una API que habla con una instancia de Google Cloud SQL (PostgreSQL).

Estoy usando el disparador de HTTP (S).

Cuando hago una lista blanca de la dirección IP de mi escritorio, puedo conectarme al Cloud SQL con el código node.js de la función desde mi máquina local. Pero cuando lo implemento, no puedo conectarme, y no puedo entender la dirección IP de HOST del servidor de la función Firebase, en la lista blanca.

¿Cómo se habla con Google Cloud SQL desde Cloud Functions para Firebase?

¡Gracias!

// Code Sample, of what's working on Localhost.
var functions = require('firebase-functions');

var pg = require('pg');
var pgConfig = {
  user: functions.config().pg.user,
  database: functions.config().pg.database,
  password: functions.config().pg.password,
  host: functions.config().pg.host
}

exports.helloSql = functions.https.onRequest((request, response) => {
  console.log('connecting...');
  try {
    client.connect(function(err) {
      if (err) throw err;

      console.log('connection success');
      console.log('querying...');

      client.query('SELECT * FROM guestbook;', function(err, result){
        if (err) throw err;

        console.log('querying success.');
        console.log('Results: ', result);
        console.log('Ending...');

        client.end(function(err){
          if (err) throw err;
          console.log('End success.');
          response.send(result);
        });
      });

    });
  } catch(er) {
    console.error(er.stack)
    response.status(500).send(er);
  }
});

Actualmente no es posible. Sin embargo, es una solicitud de función en el rastreador de problemas #36388165 :

Actualmente no se admite la conexión a Cloud SQL desde Cloud Functions, ya que el socket UNIX no existe (causando ENOENT) y no hay un rango de IP definido para la lista blanca (causando ETIMEDOUT). Una posibilidad es incluir en la lista blanca 0.0.0.0/0 de la instancia de Cloud SQL, pero esto no se recomienda por razones de seguridad.

Si esta es una característica importante para usted, le sugeriría que visite el issuetracker y marque la solicitud de características para ayudarlo a ganar popularidad.


Encontré la respuesta en una nueva discusión de #36388165 .

descargo de responsabilidad: esto no parece ser anunciado oficialmente, por lo que puede cambiar después. También solo pruebo en mysql. pero la naturaleza de esta solución, creo que debería funcionar de la misma manera que en el módulo pg (parece aceptar la ruta del socket del dominio como parámetro del host)

EDITAR (2017/12/7) : Google parece proporcionar acceso anticipado oficial , y el mismo método todavía funciona.
EDITAR (2018/07/04) : parece que hay alguien que simplemente copia y pega el código de mi ejemplo y se mete en problemas. como dice Google, debe usar el grupo de conexiones para evitar la fuga de conexiones SQL. (causa ECONNREFUSE) así que cambio un poco el código de ejemplo.

en https://issuetracker.google.com/issues/36388165#comment44 google guy dice que la instancia de la función de nube puede comunicarse con el sql de la nube a través del socket del dominio en la ruta especial '/ cloudsql / $ PROJECT_ID: $ REGION: $ DBNAME'.

De hecho, puedo conectarme y operar SQL en la nube desde debajo del código de función de la nube.

const mysql = require('mysql');
const pool = mysql.createPool({
    connectionLimit : 1,
    socketPath: '/cloudsql/' + '$PROJECT_ID:$REGION:$DBNAME',
    user: '$USER',
    password: '$PASS',
    database: '$DATABASE'
});
exports.handler = function handler(req, res) {
    //using pool instead of creating connection with function call
    pool.query(`SELECT * FROM table where id = ?`, 
                                req.body.id, function (e, results) {
        //made reply here
    });
};

Espero que esto sea de ayuda para aquellos que no pueden esperar el anuncio oficial de google.



Encuentre la región de su base de datos y el nombre de la instancia en GCP> SQL> Instancias página:

Guarde la contraseña de su base de datos en el entorno Firebase ejecutando:

$ firebase functions:config:set \
    db.user="<username>" \
    db.password="<password>" \
    db.database="<database>"

Entonces...

db.js

const { Pool } = require('pg');
const { config } = require('firebase-functions');

const project = process.env.GCP_PROJECT;
const region = 'europe-west1';
const instance = 'db';

module.exports = new Pool({
  max: 1,
  host: `/cloudsql/${project}:${region}:${instance}`,
  ...config().db
});

someFunction.js

const { https } = require('firebase-functions');
const db = require('./db');

module.exports = https.onRequest((req, res) =>
  db
    .query('SELECT version()')
    .then(({ rows: [{ version }]) => {
      res.send(version);
    }));

Vea también https://.com/a/48825037/82686 (usando la sintaxis de JavaScript moderna a través de Babel)






google-cloud-functions