Java EE FirebaseApp名称[默认值]已存在
我遇到了一个与Firebase和JavaEE相关的问题 我目前正在为我的项目编写一些Java servlet,我第一次使用Firebase是因为我想尝试一些新的东西 我的实际问题如下: 我得到了一个servlet,它负责在用户数据库中交换iOS设备令牌。这是向设备发送远程推送通知所必需的。 我在谷歌教程中也这样做过,但我得到了以下例外:Java EE FirebaseApp名称[默认值]已存在,java,jakarta-ee,firebase-realtime-database,Java,Jakarta Ee,Firebase Realtime Database,我遇到了一个与Firebase和JavaEE相关的问题 我目前正在为我的项目编写一些Java servlet,我第一次使用Firebase是因为我想尝试一些新的东西 我的实际问题如下: 我得到了一个servlet,它负责在用户数据库中交换iOS设备令牌。这是向设备发送远程推送通知所必需的。 我在谷歌教程中也这样做过,但我得到了以下例外: java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already exists! 我访问
java.lang.IllegalStateException: FirebaseApp name [DEFAULT] already exists!
我访问Firebase数据库的方式是通过JavaSDK
我使用以下代码执行此操作:
连接方法
// gets called by the servlet to configure Firebase
public static void connect() {
try {
// for authentication purpose
Map<String, Object> auth = new HashMap<>();
auth.put("uid", "my-service-account");
// Setting up the FirebaseOptions object
// constant FIREBASE_DATABASE_URL = "url to my database"
// constant FIREBASE_KEY_PATH = "path to my json key"
options = new FirebaseOptions.Builder()
.setDatabaseUrl(FIREBASE_DATABASE_URL)
.setServiceAccount(new FileInputStream(FIREBASE_KEY_PATH))
.setDatabaseAuthVariableOverride(auth)
.build();
FirebaseApp.initializeApp(options);
// calling the method for exchanging the token
exchangeIosDeviceToken("testmail@example.com", "5bf53173c9ef0a37638f3ddaa59cf2c0687c14ca0dcd47ccf57f9f09bd6368ab");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
public static boolean exchangeIosDeviceToken(String email, String newDeviceToken) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
// getting a reference to my "employee" child
DatabaseReference employeeReference = database.getReference("/employee");
Map<String, Object> employeeUpdates = new HashMap<>();
// updating the device token with child "iosDeviceToken" of "employee"
employeeUpdates.put(email+"/iosDeviceToken", newDeviceToken);
// update the actual children
employeeReference.updateChildren(employeeUpdates);
return true;
}
//被servlet调用以配置Firebase
公共静态void connect(){
试一试{
//用于身份验证目的
Map auth=new HashMap();
授权输入(“uid”,“我的服务帐户”);
//设置FirebaseOptions对象
//常量FIREBASE\u DATABASE\u URL=“指向我的数据库的URL”
//常量FIREBASE\u KEY\u PATH=“指向我的json密钥的路径”
选项=新的FirebaseOptions.Builder()
.setDatabaseUrl(FIREBASE_数据库_URL)
.setServiceAccount(新文件输入流(FIREBASE\u密钥\u路径))
.setDatabaseAuthVariableOverride(身份验证)
.build();
FirebaseApp.initializeApp(选项);
//调用用于交换令牌的方法
exchangeIosDeviceToken(“testmail@example.com“,“5bf53173c9ef0a37638f3ddaa59cf2c0687c14ca0dcd47ccf57f9f09bd6368ab”);
}捕获(FileNotFoundException ex){
例如printStackTrace();
}
}
exchangeIosDeviceToken方法
// gets called by the servlet to configure Firebase
public static void connect() {
try {
// for authentication purpose
Map<String, Object> auth = new HashMap<>();
auth.put("uid", "my-service-account");
// Setting up the FirebaseOptions object
// constant FIREBASE_DATABASE_URL = "url to my database"
// constant FIREBASE_KEY_PATH = "path to my json key"
options = new FirebaseOptions.Builder()
.setDatabaseUrl(FIREBASE_DATABASE_URL)
.setServiceAccount(new FileInputStream(FIREBASE_KEY_PATH))
.setDatabaseAuthVariableOverride(auth)
.build();
FirebaseApp.initializeApp(options);
// calling the method for exchanging the token
exchangeIosDeviceToken("testmail@example.com", "5bf53173c9ef0a37638f3ddaa59cf2c0687c14ca0dcd47ccf57f9f09bd6368ab");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
public static boolean exchangeIosDeviceToken(String email, String newDeviceToken) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
// getting a reference to my "employee" child
DatabaseReference employeeReference = database.getReference("/employee");
Map<String, Object> employeeUpdates = new HashMap<>();
// updating the device token with child "iosDeviceToken" of "employee"
employeeUpdates.put(email+"/iosDeviceToken", newDeviceToken);
// update the actual children
employeeReference.updateChildren(employeeUpdates);
return true;
}
public静态布尔交换iosdevicetoken(字符串email,字符串newDeviceToken){
FirebaseDatabase=FirebaseDatabase.getInstance();
//获取我的“雇员”孩子的参考资料
DatabaseReference employeeReference=database.getReference(“/employee”);
Map employeeUpdates=new HashMap();
//使用“employee”的子项“iosDeviceToken”更新设备令牌
employeeUpdates.put(email+“/iosDeviceToken”,newDeviceToken);
//更新实际的子项
employeeReference.updateChildren(EmployeeUpdate);
返回true;
}
有趣的是,当我试图在一个独立的主类中执行这段代码(用main方法替换connect方法)时,代码正常工作
在你说“有很多关于这个话题的问题”之前。。。它们几乎都与安卓系统有关,与我的问题相关的问题很少得到回答
问候解决了问题
问题是:
每次传入请求时,我都会调用connect方法
解决方案:
只调用connect方法一次。(ServletContextListener)我解决这个问题的方法是调用
FirebaseApp.getInstance().delete()代码>对于未来的用户,您可以检查默认应用程序是否已初始化
FirebaseApp firebaseApp = null;
List<FirebaseApp> firebaseApps = FirebaseApp.getApps();
if(firebaseApps!=null && !firebaseApps.isEmpty()){
for(FirebaseApp app : firebaseApps){
if(app.getName().equals(FirebaseApp.DEFAULT_APP_NAME))
firebaseApp = app;
}
}
else
firebaseApp = FirebaseApp.initializeApp(options);
FirebaseApp-FirebaseApp=null;
列出firebaseApps=firebaseApps.getApps();
if(firebaseApps!=null&&!firebaseApps.isEmpty()){
用于(FirebaseApp应用程序:FirebaseApp){
if(app.getName().equals(FirebaseApp.DEFAULT\u app\u NAME))
firebaseApp=app;
}
}
其他的
firebaseApp=firebaseApp.initializeApp(选项);
出现此异常是因为您试图再次创建[默认值]
FirebaseApp,只需在初始化之前添加验证以检查它是否存在,如下所示:
if(FirebaseApp.getInstance(FirebaseApp.DEFAULT_APP_NAME) != null) {
return;
}
我的解决方案
package com.zs.configuration;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOpt`enter code here`ions;
import com.google.firebase.auth.FirebaseAuth;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.FileInputStream;
@WebListener
public class MyAppServletContextListener
implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
}
//Run this before web application is started
@Override
public void contextInitialized(ServletContextEvent arg0) {
try {
FileInputStream serviceAccount = new FileInputStream(getClass().getClassLoader().getResource("zs.json").getFile());
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://zs.firebaseio.com")
.build();
FirebaseApp firebaseApp = FirebaseApp.initializeApp(options);
FirebaseAuth.getInstance(firebaseApp);
}catch (Exception exc){
System.out.println("Firebase exception "+exc);
}
System.out.println("ServletContextListener started");
}
}
在我的申请课上
@ServletComponentScan
@SpringBootApplication
public class ZSApplication {
public static void main(String[] args) {
SpringApplication.run(ZSApplication.class, args);
}
}
.delete()在运行11.0.1I版时似乎不存在。我在Servlet的init()
方法中初始化我的FirebaseApp
,并且会一直出现此错误,但此解决方案有效!创建一个类,实现ServletContextListener
在contextInitialized()
方法中重写初始化FirebaseApp所需的两个方法。