Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Daeda88 opened this issue Apr 15, 2024 · 1 comment · May be fixed by #5903
Open
Labels
api: database type: bug Something isn't working

Comments

@Daeda88
Copy link

Daeda88 commented Apr 15, 2024

[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:

  • For general technical questions, post a question on StackOverflow
    with the firebase tag.
  • For general Firebase discussion, use the firebase-talk
    google group.
  • For help troubleshooting your application that does not fall under one
    of the above categories, reach out to the personalized
    Firebase support channel.

[REQUIRED] Step 2: Describe your environment

  • Android Studio version: Iguana 2023.2.1 Patch 2
  • Firebase Component: Database
  • Component version: 20.3.1

[REQUIRED] Step 3: Describe the problem

When running a test connected for a FirebaseEmulator from the Android Emulator, goOnline is unable to reconnect to the database, despite being able to connect fine at first. It seems the 10.0.2.2 address gets overwritten by localhost which fails on reconnection.

Steps to reproduce:

See code below:

  • Connect to a Firebase Database running on an emulator through the Android emulator, specify the host 10.0.2.2 explicitly
  • Call goOffline()
  • Call goOnline()
  • Attempt to read any data will fail from this point on

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
Copy link
Contributor

argzdev commented Apr 19, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: database type: bug Something isn't working
Projects
None yet
3 participants