1

How do I run Firebase admin on NodeJS when the computer is behind a corporate proxy?

npm has already config proxy and https-proxy. npm commands executes alright.

Firebase however, tries to directly access the internet:

Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "connect ETIMEDOUT 216.58.203.45:443".

I tried to update the faye-websocket\lib\faye\websocket\client.js under firebase-admin to read

  var Client = function(_url, protocols, options) {
  options = options || {};
  options.proxy = {
    origin: 'http://proxy.server.local:8080'
  };

I tried several variations, but nodejs is still trying to directly access 216.58.203.45:443. What else should I update to make it work?

AL.
  • 36,815
  • 10
  • 142
  • 281
Alex
  • 368
  • 5
  • 17
  • The error you are getting is not coming from the Realtime Database, it is coming from the Google endpoint (`https://accounts.google.com/o/oauth2/token`) used to exchange a JWT minted from your service account to a Google OAuth2 access token. You might need to whitelist that endpoint. – jwngr Mar 30 '17 at 17:11
  • Thanks for the response. I can access the URL from browser, and other google auth related URLs works fine with browser. Yes you are right, it is about the token refresh. It is not going via the proxy correctly, but I have no idea how to force it to. – Alex Mar 31 '17 at 02:36
  • Sorry, I'm not sure I know much about how to bypass proxies. You probably need to talk to whoever runs your corporate proxy. – jwngr Apr 01 '17 at 00:56

2 Answers2

3

This is how I run my FirebaseAdmin behind a corporate proxy.

Please install the latest Firebase Admin Node version, which is v6.4.0 and above. Besides, you also require to install a tunnel2 library.

npm install firebase-admin@6.4.0
npm install tunnel2


var admin = require('firebase-admin');
var serviceAccount = require('path/to/serviceAccountKey.json');
const tunnel = require('tunnel2')
// Create your Proxy Agent 
// Please choose your tunneling method accordingly, my case
// is httpsoverHttp, yours might be httpsoverHttps
const proxyAgent = tunnel.httpsOverHttp({
    proxy: {
      host: 'yourProxyHost',
      port: yourProxyPort,
      proxyAuth: 'user:password' // Optional, required only if your proxy require authentication
    }
});
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount, proxyAgent),
  databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});

Hope it helps you. I wrote an article for this. You can refer there the article here

Tek Loon
  • 206
  • 1
  • 10
0

Since it took me quiet a while to figure out how it works here it is for anybody searching:

const proxyAgent = tunnel.httpsOverHttp({
  proxy: {
    host: 'YOUR_PROXY_HOST',
    port: YOUR_PROXY_PORT,
    proxyAuth: 'user:password', // Optional, required only if your proxy require authentication
  },
});

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount, proxyAgent),
  databaseURL: 'https://<DATABASE_NAME>.firebaseio.com',
  httpAgent: proxyAgent, //this is what I was missing
});
CRoNiC
  • 329
  • 2
  • 4
  • 14
  • It works for me even though I didn't have the httpAgent: object in the initializeApp() call – Alex Apr 16 '21 at 11:15
  • your Firebase Admin SDK instance is running behind a proxy and it worked without? for me it didn't and I had to search pretty long to find out what was missing so I commented it here. It was only mentioned here https://github.com/firebase/firebase-admin-node/issues/719 in hiranya's last comment – CRoNiC Apr 16 '21 at 11:56
  • I just checked all my scripts. Some have the httpgent:, some don't (only provide inside the admin.credential.cert()). But all of them work behind a proxy. By the way, your code is missing a comma before httpAgent: – Alex Apr 17 '21 at 14:34
  • Now I finally understand. RTDB and firestore do not use the httpAgent field of initialzeApp(). Therefore, it doesn't matter. They need websockets and cannot be used behind a proxy. – Alex Jun 30 '22 at 00:18