firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.86k stars 893 forks source link

connectDatabaseEmulator fail if host is "localhost" #6958

Open PaoloOranges opened 1 year ago

PaoloOranges commented 1 year ago

[REQUIRED] Describe your environment

[REQUIRED] Describe the problem

When call connectDatabaseEmulator with parameter localhost, to use emulator suite: set() function from firebase/database does not resolve and no writing is done on the database. If 127.0.0.1 is used instead, logic works as expected

Steps to reproduce:

  1. Start firebase emulator locally
  2. Initialize firebase (with RealTime Database)
  3. Get teh Database ref
  4. use connectDatabaseEmulator to bind the realtime database reference to the local emulator
  5. Call set() to write to the database

Expected Result: Data are written to the real time database (local emulator); promise is resolved.

Actual Result: No data is written to DB, neither Resolve nor Error callbacks are called.

Relevant Code:

// Firebase config here up
const app = initializeApp(FIREBASE_CONFIG);
setLogLevel("debug");
enableLogging(true);

const realtimeDB = getDatabase(app);
connectDatabaseEmulator(realtimeDB, 'localhost', 9000);

set(ref(realtimeDB, "test-path"), {
  name: "Paolo",
  someValue: 31
}).then(() => {
  console.log("RTDB OK")
}).catch((error) => {
  console.log("Some kind of error: " + error);
});

Output from Log:

NOTE : I replaced my project name with <project-id>

[2023-01-19T10:46:36.997Z]  @firebase/database: p:0: Browser went online. 
[2023-01-19T10:46:39.928Z]  @firebase/database: 0: set {"path":"/test-path","value":{"name":"Paolo","someValue":31},"priority":null} 
[2023-01-19T10:46:41.774Z]  @firebase/database: p:0: Buffering put: /test-path 
[2023-01-19T10:46:41.779Z]  @firebase/database: p:0: Making a connection attempt
[2023-01-19T10:46:41.781Z]  @firebase/database: getToken() completed. Creating connection.
[2023-01-19T10:46:41.782Z]  @firebase/database: c:0:0: Connection created
[2023-01-19T10:46:41.798Z]  @firebase/database: c:0:0:0 Websocket connecting to ws://localhost:9000/.ws?v=5&p=1:23966653353:web:d5c91c923ddb033c0f82b8&ns=<project-id> 
[2023-01-19T10:46:41.803Z]  @firebase/database: c:0:0:0 WebSocket error.  Closing connection.
[2023-01-19T10:46:41.804Z]  @firebase/database: c:0:0:0 Network error: ws://localhost:9000/.ws?v=5&p=1:23966653353:web:d5c91c923ddb033c0f82b8&ns=<project-id>: connect ECONNREFUSED ::1:9000
[2023-01-19T10:46:41.804Z]  @firebase/database: c:0:0:0 WebSocket is closing itself
[2023-01-19T10:46:41.805Z]  @firebase/database: c:0:0:0 Websocket connection was disconnected.
[2023-01-19T10:46:41.806Z]  @firebase/database: c:0:0: Realtime connection failed.
[2023-01-19T10:46:41.807Z]  @firebase/database: c:0:0: Closing realtime connection.
[2023-01-19T10:46:41.807Z]  @firebase/database: c:0:0: Shutting down all connections
[2023-01-19T10:46:41.808Z]  @firebase/database: p:0: data client disconnected
[2023-01-19T10:46:41.808Z]  @firebase/database: p:0: Trying to reconnect in 376.4805688137009ms
[2023-01-19T10:46:41.809Z]  @firebase/database: 0: onDisconnectEvents
google-oss-bot commented 1 year ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

maneesht commented 1 year ago

@PaoloOranges I just tried connecting to localhost using your code and wasn't able to reproduce the issue. Out of curiosity, are you able to start up another HTTP server and access it through localhost?

PaoloOranges commented 1 year ago

Hi @maneesht . Actually I haven't tried what you said. I'm going to test it. However I have to add that:

const firestoreDB = getFirestore();
connectFirestoreEmulator(firestoreDB, 'localhost', 8080);

works perfectly. But if I use http.request() with localhost it fails too while it works with 127.0.0.1. e.g. (to call the URL to clean local firestore db) the following code return me the same error code connect ECONNREFUSED ::1:8080

  const requestOptions = 
  {
      host: 'localhost',
      port: 8080,
      method: 'DELETE',
      path: CLEAN_FIRESTORE_PATH
  };
const req = http.request(requestOptions, (res) => {
    //...
}).on('error', (err) => 
{
    //...
});
req.end();

while the following one completes with no error:

  const requestOptions = 
  {
      host: '127.0.0.1',
      port: 8080,
      method: 'DELETE',
      path: CLEAN_FIRESTORE_PATH
  };
const req = http.request(requestOptions, (res) => {
    //...
}).on('error', (err) => 
{
    //...
});
req.end();

Also, postman requests via localhost to the emulator work.

I've just tried to start a local server (nodejs) and I can connect to localhost with no problem.

kirill-dev-pro commented 1 year ago

I have very similar error with firestore emulator and set() call. It only happens in cypress and never on actual browser. I use version 8 of firebase. Request is ok but data is never written on db and promise never resolves