我一直在尝试在使用Spring的服务器端集成一些Firebase功能。
显然,Spring可以决定多次启动public static void main
(从现在开始,我称其为“ main”)方法。 (为什么?)
问题是Firebase需要我们的服务器进行身份验证才能使用某些Admin SDK功能(例如,验证idToken的签名)。我以为这通常会用在main
方法中,但实际上它被调用了两次,这导致了FirebaseApp with name [DEFAULT] already exist.
异常。
我想有两种解决方案,所以我会问两个问题:
main
? (为什么还要这么做?)private static boolean
属性就足够了,但是我觉得应该有一种更好的方法来解决这个问题。)编辑:似乎“布尔”方法甚至不起作用。我猜想Spring的第二个调用是异步的。
编辑:
这里是main()
代码(authenticateServer()
方法在Spring启动之前运行了两次):
package hackqc18.Acclimate;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import hackqc18.Acclimate.authentication.VerifyToken;
import hackqc18.Acclimate.notifications.PushNotifServiceImpl;
import java.io.FileInputStream;
import java.util.ArrayList;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class AcclimateApplication {
public static void main(String[] args) {
// Nécessaire!
authenticateServer();
SpringApplication.run(AcclimateApplication.class, args);
}
/**
* Utilisé pour démontrer comment utiliser certaines fonctionnalités.
*/
private static void demonstrationTemplate() {
// [ Exemple de PUSH NOTIFICATION vers 2 appareils ]
ArrayList<String> listOfDevices = new ArrayList<>();
listOfDevices.add("...");
listOfDevices.add("...");
PushNotifServiceImpl.sendPushNotification(listOfDevices,"Test","Backend SPAMMMMMMM!");
// [ Fin de l'exemple de notifs ]
// [ Exemple de vérification d'un "idToken" et extraction du UID ]
String idToken = "...";
String uID = VerifyToken.verifyIdToken(idToken);
System.out.println("Identified uID: " + uID);
// [ Fin de l'exemple ]
// TODO: CETTE MÉTHODE NE FONCTIONNE TOUJOURS PAS !!
// [ Exemple d'envoie d'une notif à un appareil ]
String registrationToken = "...";
PushNotifServiceImpl.sendThroughGoogle(registrationToken);
// [ Fin de l'envoie ]
}
/**
* Admin SDK API (Firebase) - nécessaire
* Pour authentifier le serveur d'Acclimate au serveur de Firebase.
* Permet d'utiliser les fonctionnalités de l'Admin SDK.
*/
private static void authenticateServer() {
try {
// [ Obtenir l'instance de Firebase App pour utiliser Admin SDK ]
FileInputStream serviceAccount = new FileInputStream("abc.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://bob.com/")
.build();
FirebaseApp.initializeApp(options);
// [ Fin de la validation du Admin SDK API ]
} catch (Exception e) {
e.printStackTrace();
}
// TODO: Juste là pour des fins de démonstration.
demonstrationTemplate();
}
}
编辑:添加更多代码。
这里是AppConfig.java
:
package hackqc18.Acclimate;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@ComponentScan("hackqc18")
@EnableWebMvc
public class AppConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
}
这里是pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hackqc18</groupId>
<artifactId>Acclimate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Acclimate</name>
<description>Hackathon Québec 2018</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<geotools.version>18.1</geotools.version>
</properties>
<dependencies>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geometry</artifactId>
<version>${geotools.version}</version>
</dependency>
<!-- <dependency> <groupId>com.bedatadriven</groupId> <artifactId>jackson-datatype-jts</artifactId>
<version>2.2</version> </dependency> -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<!-- Jeremi added Firebase Admin SDK -->
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>6.3.0</version>
</dependency>
<!-- Firebase Admin SDK-->
<!-- <dependency> -->
<!-- <groupId>org.apache.derby</groupId> -->
<!-- <artifactId>derby</artifactId> -->
<!-- <scope>runtime</scope> -->
<!-- </dependency> -->
<!-- <dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency> -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- >
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>
<-->
</plugins>
</build>
<repositories>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>boundless</id>
<name>Boundless Maven Repository</name>
<url>http://repo.boundlessgeo.com/main</url>
</repository>
</repositories>
</project>
这里是nbactions.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<actionName>run</actionName>
<packagings>
<packaging>jar</packaging>
</packagings>
<goals>
<goal>process-classes</goal>
<goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
</goals>
<properties>
<exec.args>-classpath %classpath hackqc18.Acclimate.AcclimateApplication</exec.args>
<exec.executable>java</exec.executable>
</properties>
</action>
</actions>
编辑:这是我在Spring实际启动之前收到的消息。我在main()
中的方法在此消息之前被调用一次,在此消息之后被调用一次。然后,Spring实际上开始了。
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-geojson\18.1\gt-geojson-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-main-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-api-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jdom-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/json-simple-1.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/commons-lang-2.6.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-main\18.1\gt-main-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-api-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jdom-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-api\18.1\gt-api-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-referencing\18.1\gt-referencing-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-metadata\18.1\gt-metadata-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/jai_core-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/jts-core-1.14.0.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-opengis\18.1\gt-opengis-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-opengis/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-opengis/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-opengis/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-geometry\18.1\gt-geometry-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-main-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-api-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jdom-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\io\grpc\grpc-netty-shaded\1.10.1\grpc-netty-shaded-1.10.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/grpc-core-1.10.1.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/grpc-context-1.10.1.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/gson-2.7.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/opencensus-contrib-grpc-metrics-0.11.0.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/opencensus-api-0.11.0.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/guava-19.0.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/error_prone_annotations-2.1.2.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/jsr305-3.0.0.jar
12:51:34.090 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : []
12:51:34.125 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Excluded patterns for restart : [/spring-boot-starter-[\w-]+/, /spring-boot/target/classes/, /spring-boot-starter/target/classes/, /spring-boot-devtools/target/classes/, /spring-boot-actuator/target/classes/, /spring-boot-autoconfigure/target/classes/]
12:51:34.125 [main] DEBUG org.springframework.boot.devtools.restart.ChangeableUrls - Matching URLs for reloading : [file:/C:/Users/PC/Documents/GitHub/acclimateServer/target/classes/]
2018-08-09 12:51:36.273 DEBUG 10984 --- [ restartedMain] .c.l.ClasspathLoggingApplicationListener : Application started with classpath: [file:/C:/Users/PC/Documents/GitHub/acclimateServer/target/classes/]
答案 0 :(得分:0)
发现devtools
是造成这种奇怪行为的原因。我只是删除了pom.xml
的这一部分来解决此问题:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>