【DataGrip】IntelliJ IDEAを使ってDBの差分を取ってみよう!【データベース】
野田竣介
フェルメール株式会社
プッシュ通知を送信するためにFirebase Admin SDKを導入しました。
しばらく動作確認をしているとアプリケーションのリロードで以下のエラーが発生することが発覚!
java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already exists!
at com.google.common.base.Preconditions.checkState(Preconditions.java:510)
at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:227)
at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:218)
at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:205)
at utils.FirebaseUtils.(FirebaseUtils.java:47)
at utils.FirebaseUtils$$FastClassByGuice$$e54a4c4d.newInstance()
at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:114)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:91)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:168)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39)
at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:211)
at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:182)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109)
at com.google.inject.Guice.createInjector(Guice.java:87)
at com.google.inject.Guice.createInjector(Guice.java:78)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:171)
at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:241)
at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:138)
at akka.stream.impl.fusing.MapAsyncUnordered$$anon$26.onPush(Ops.scala:1304)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:519)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:482)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:588)
at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:472)
at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:563)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:745)
at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:760)
at akka.actor.Actor.aroundReceive(Actor.scala:517)
at akka.actor.Actor.aroundReceive$(Actor.scala:515)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:670)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:588)
at akka.actor.ActorCell.invoke(ActorCell.scala:557)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:258)
at akka.dispatch.Mailbox.run(Mailbox.scala:225)
at akka.dispatch.Mailbox.exec(Mailbox.scala:235)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
そこで、このエラーを解消します!
FirebaseAppに同じ名前のAppを登録しようとしてエラーになっているみたいです。
Firebaseのコンソール上に表示されているサンプルコードを利用している場合、初期化はこのように行っていると思います。
FileInputStream serviceAccount =
new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://project-name.firebaseio.com")
.build();
FirebaseApp.initializeApp(options);
最後の行の
FirebaseApp.initializeApp(options);
ここでエラーになっていました。
最後の行をこのように変更しました。
FirebaseApp firebaseApp;
List<FirebaseApp> apps = FirebaseApp.getApps();
if (apps.size() == 0) {
firebaseApp = FirebaseApp.initializeApp(options);
} else {
firebaseApp = apps.get(0);
}
次のような流れで処理するように変更しました。
ありがたいことに起動しているAppを取得するメソッドがあったのであっさり解決しました。
これでリロードしたときは初期化済みのAppを返してくれます。
起動しているAppを取得することができなかったら、面倒なことになっていましたね。
わざわざ判定するのも面倒なので、どうにかしてSDK側で吸収してほしいものですが…
しばらくこのコードで利用していますが、特にバグはないので大丈夫だと思います。
今は簡単にプッシュ通知を飛ばせて良いですね!