You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ktor部署虚拟机出现FirebaseApp [DEFAULT]不存在异常求助

Ktor项目部署到虚拟机后Firebase初始化异常

异常信息

Exception in thread "DefaultDispatcher-worker-1" java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn't exist.
at com.google.firebase.FirebaseApp.getInstance(FirebaseApp.java:161)
at com.google.firebase.FirebaseApp.getInstance(FirebaseApp.java:132)
at com.google.firebase.database.FirebaseDatabase.getInstance(FirebaseDatabase.java:81)
at com.example.ApplicationKt.deleteOldEvents(Application.kt:532)
at com.example.ApplicationKt$module$3.invokeSuspend(Application.kt:187)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)

本地运行正常,但部署到虚拟机后抛出上述异常,请问该异常产生的原因是什么?

项目代码

@Serializable
data class Request(val receiverUid: String, val senderUid: String)

fun main(args: Array<String>) {
    try {
        val serviceAccount = FileInputStream("src/main/resources/google-services.json")

        val options = FirebaseOptions.Builder()
            .setCredentials(GoogleCredentials.fromStream(serviceAccount))
            .setDatabaseUrl("there is my url for database")
            .build()

        if(FirebaseApp.getApps().isEmpty()) {
            FirebaseApp.initializeApp(options)
            println("FirebaseApp initialized successfully")
        }

    } catch (e: Exception) {
        println("Error initializing FirebaseApp: ${e.message}")
    }

    embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module).start(wait = true)
}

fun Application.module() {
    install(ContentNegotiation) {
        gson {
            setPrettyPrinting()
        }
    }

    launch {
        while(true) {
            deleteOldEvents()
            delay(1000 * 3600 * 60 * 24)
        }
    }
    install(Routing) {
        get("/") {
            call.respondText("Hello World!")
        }
          // other code
    }
}

suspend fun deleteOldEvents() {

    val dbEvent = FirebaseDatabase.getInstance().getReference("current_events")
    val dbGroups = FirebaseDatabase.getInstance().getReference("groups")
    val reports = FirebaseDatabase.getInstance().getReference("reports")

    val currentTime = Instant.now().epochSecond

    suspendCoroutine<Unit> { continuation ->
        dbEvent.addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                dataSnapshot.children.forEach { eventSnapshot ->
                    val timestamp = eventSnapshot.child("timestamp").value as Long
                    if (currentTime - timestamp > 5 * 24 * 60 * 60) {
                        eventSnapshot.ref.removeValue() { error, _ ->
                            
                           continuation.resume(Unit)
                            
                        }
                    }
                }
            }

            override fun onCancelled(error: DatabaseError) {
                continuation.resumeWithException(error.toException())
            }
        })
    }
}

异常原因分析

  • 配置文件路径错误:本地开发时src/main/resources/google-services.json的路径有效,但项目打包部署后,资源文件会被放入classpath根目录,FileInputStream无法通过该相对路径找到文件,直接导致Firebase初始化失败。
  • 初始化失败未终止程序:main函数中捕获初始化异常后仅打印日志,仍继续启动服务器。后续deleteOldEvents调用FirebaseDatabase.getInstance()时,因没有已初始化的FirebaseApp实例,抛出异常。
  • 协程执行时机偏差:虚拟机环境下的类加载、线程调度逻辑与本地不同,可能导致module中的launch协程先于Firebase初始化完成执行,触发未初始化的问题。

解决方案

  1. 正确读取classpath资源:替换文件读取方式为classpath加载:
    val serviceAccount = Application::class.java.getResourceAsStream("/google-services.json")
    requireNotNull(serviceAccount) { "google-services.json not found in classpath" }
    
  2. 初始化失败终止程序:在catch块中终止程序,避免后续无意义的执行:
    catch (e: Exception) {
        println("Error initializing FirebaseApp: ${e.message}")
        e.printStackTrace()
        System.exit(1)
    }
    
  3. 显式指定DEFAULT实例:确保初始化的是默认实例,避免名称不匹配:
    FirebaseApp.initializeApp(options, FirebaseApp.DEFAULT_APP_NAME)
    

内容的提问来源于stack exchange,提问作者veterok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:43:19