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初始化完成执行,触发未初始化的问题。
解决方案
- 正确读取classpath资源:替换文件读取方式为classpath加载:
val serviceAccount = Application::class.java.getResourceAsStream("/google-services.json") requireNotNull(serviceAccount) { "google-services.json not found in classpath" } - 初始化失败终止程序:在catch块中终止程序,避免后续无意义的执行:
catch (e: Exception) { println("Error initializing FirebaseApp: ${e.message}") e.printStackTrace() System.exit(1) } - 显式指定DEFAULT实例:确保初始化的是默认实例,避免名称不匹配:
FirebaseApp.initializeApp(options, FirebaseApp.DEFAULT_APP_NAME)
内容的提问来源于stack exchange,提问作者veterok
相关产品推荐
相关产品推荐

