firebase / firebase-android-sdk

Firebase Android SDK
https://firebase.google.com
Apache License 2.0
2.27k stars 577 forks source link

FirebaseDatabase.GoOnline does not work when connecting to a Firebase Emulator on Android Emulators #5870

Open Daeda88 opened 6 months ago

Daeda88 commented 6 months ago

[READ] Step 1: Are you in the right place?

Issues filed here should be about bugs in the code in this repository. If you have a general question, need help debugging, or fall into some other category use one of these other channels:

[REQUIRED] Step 2: Describe your environment

Steps to reproduce:

See code below:

Relevant Code:

@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @Test
    fun testDatabase() {
        // Context of the app under test.
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        assertEquals("com.example.testandroid", appContext.packageName)

        val app = Firebase.initialize(appContext,
            FirebaseOptions.Builder().
                setApplicationId("1:846484016111:ios:dd1f6688bad7af768c841a").
                setApiKey("AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0").
                setDatabaseUrl("https://fir-kotlin-sdk-default-rtdb.firebaseio.com")
                    .setStorageBucket("fir-kotlin-sdk.appspot.com")
                .setProjectId("fir-kotlin-sdk-default-rtdb")
                    .build()
        )

        val database = Firebase.database(app).apply {
            useEmulator("10.0.2.2", 9000)
            setLogLevel(Logger.Level.DEBUG)
        }

        runBlocking {
            val events = database.connectedEvents().shareIn(MainScope(), SharingStarted.Eagerly)
            events.first { it }
            database.goOffline()
            events.first { !it }
            database.goOnline()
            events.first { it }
        }
    }

    private fun FirebaseDatabase.connectedEvents(): Flow<Boolean> {
        val result = MutableSharedFlow<Boolean>(replay = 1)
        val listener = object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                (snapshot.value as? Boolean)?.let {
                    result.tryEmit(it)
                }
            }

            override fun onCancelled(error: DatabaseError) {

            }
        }
        val reference = getReference(".info/connected")
        reference.addValueEventListener(listener)
        return flow {
            emitAll(result)
        }.onCompletion {
            reference.removeEventListener(listener)
        }
    }
}

Fails with:

ws_2 - WebSocket error.
                                                                                                    com.google.firebase.database.tubesock.WebSocketException: error while creating socket to ws://127.0.0.1:9000/.ws?ns=fir-kotlin-sdk-default-rtdb&v=5&ls=j5cA65fhPPz2drB73AHOpHAG9ezhZyvn
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.createSocket(WebSocket.java:301)
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.runReader(WebSocket.java:360)
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.access$000(WebSocket.java:47)
                                                                                                        at com.google.firebase.database.tubesock.WebSocket$2.run(WebSocket.java:143)
                                                                                                        at java.lang.Thread.run(Thread.java:1012)
                                                                                                    Caused by: java.net.ConnectException: failed to connect to /127.0.0.1 (port 9000) from /:: (port 33788): connect failed: ECONNREFUSED (Connection refused)
                                                                                                        at libcore.io.IoBridge.connect(IoBridge.java:187)
                                                                                                        at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
                                                                                                        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
                                                                                                        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
                                                                                                        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
                                                                                                        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
                                                                                                        at java.net.Socket.connect(Socket.java:646)
                                                                                                        at java.net.Socket.connect(Socket.java:595)
                                                                                                        at java.net.Socket.<init>(Socket.java:475)
                                                                                                        at java.net.Socket.<init>(Socket.java:243)
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.createSocket(WebSocket.java:297)
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.runReader(WebSocket.java:360) 
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.access$000(WebSocket.java:47) 
                                                                                                        at com.google.firebase.database.tubesock.WebSocket$2.run(WebSocket.java:143) 
                                                                                                        at java.lang.Thread.run(Thread.java:1012) 
                                                                                                    Caused by: android.system.ErrnoException: connect failed: ECONNREFUSED (Connection refused)
                                                                                                        at libcore.io.Linux.connect(Native Method)
                                                                                                        at libcore.io.ForwardingOs.connect(ForwardingOs.java:201)
                                                                                                        at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:158)
                                                                                                        at libcore.io.ForwardingOs.connect(ForwardingOs.java:201)
                                                                                                        at libcore.io.IoBridge.connectErrno(IoBridge.java:201)
                                                                                                        at libcore.io.IoBridge.connect(IoBridge.java:179)
                                                                                                        at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142) 
                                                                                                        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390) 
                                                                                                        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230) 
                                                                                                        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212) 
                                                                                                        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436) 
                                                                                                        at java.net.Socket.connect(Socket.java:646) 
                                                                                                        at java.net.Socket.connect(Socket.java:595) 
                                                                                                        at java.net.Socket.<init>(Socket.java:475) 
                                                                                                        at java.net.Socket.<init>(Socket.java:243) 
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.createSocket(WebSocket.java:297) 
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.runReader(WebSocket.java:360) 
                                                                                                        at com.google.firebase.database.tubesock.WebSocket.access$000(WebSocket.java:47) 
                                                                                                        at com.google.firebase.database.tubesock.WebSocket$2.run(WebSocket.java:143) 
                                                                                                        at java.lang.Thread.run(Thread.java:1012) 
argzdev commented 6 months ago

Thanks for the well detailed report, @Daeda88. I was able to reproduce the same behavior. I'll go ahead and report this to our engineers.