# #java #spring-boot #google-cloud-platform #google-cloud-firestore #google-cloud-storage
Вопрос:
У меня есть проект, в котором я вызываю Google Cloud Storage API из Firebase Cloud FireStore API. Это мой код Firebase перед добавлением зависимостей облачного хранилища Google.
Основной класс
package com.example.firebase.springbootfirebasedemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootFirebaseDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootFirebaseDemoApplication.class, args);
}
}
Это мой контроллер ОТДЫХА
package com.example.firebase.springbootfirebasedemo.controller;
import com.example.firebase.springbootfirebasedemo.entity.Review;
import com.example.firebase.springbootfirebasedemo.service.ReviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.concurrent.ExecutionException;
@RestController
@RequestMapping("/api")
public class ReviewController {
@Autowired
private ReviewService reviewService;
@PostMapping("/reviews")
public String saveReview(@RequestBody Review review) throws ExecutionException, InterruptedException {
return reviewService.saveReview(review);
}
@GetMapping("/reviews/{name}")
public Review getReview(@PathVariable String name) throws ExecutionException, InterruptedException {
return reviewService.getReviewDetailsByname(name);
}
@GetMapping("/reviews")
public List<Review> getAllReviews() throws ExecutionException, InterruptedException {
return reviewService.getAllReviews();
}
@PutMapping("/reviews")
public String updateReview(@RequestBody Review review) throws ExecutionException, InterruptedException {
return reviewService.updateReview(review);
}
@DeleteMapping("/reviews/{name}")
public String deleteReview(@PathVariable String name) throws ExecutionException, InterruptedException {
return reviewService.deleteReview(name);
}
}
Это мой класс обслуживания
package com.example.firebase.springbootfirebasedemo.service;
import com.example.firebase.springbootfirebasedemo.entity.Review;
import com.google.api.core.ApiFuture;
import com.google.cloud.firestore.DocumentReference;
import com.google.cloud.firestore.DocumentSnapshot;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.WriteResu<
import com.google.firebase.cloud.FirestoreClient;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
@Service
public class ReviewService {
private static final String COLLECTION_NAME ="Reviews";
public String saveReview(Review review) throws ExecutionException, InterruptedException {
Firestore dbFirestore= FirestoreClient.getFirestore();
ApiFuture<WriteResult> collectionApiFuture=dbFirestore.collection(COLLECTION_NAME).document(review.getName()).set(review);
return collectionApiFuture.get().getUpdateTime().toString();
}
public Review getReviewDetailsByname(String name) throws ExecutionException, InterruptedException {
Firestore dbFirestore= FirestoreClient.getFirestore();
DocumentReference documentReference=dbFirestore.collection(COLLECTION_NAME).document(name);
ApiFuture<DocumentSnapshot> future=documentReference.get();
DocumentSnapshot document=future.get();
Review review=null;
if(document.exists()) {
review = document.toObject(Review.class);
return review;
}else{
return null;
}
}
public List<Review> getAllReviews() throws ExecutionException, InterruptedException {
Firestore dbFirestore= FirestoreClient.getFirestore();
Iterable<DocumentReference> documentReference=dbFirestore.collection(COLLECTION_NAME).listDocuments();
Iterator<DocumentReference> iterator=documentReference.iterator();
List<Review> reviewList=new ArrayList<>();
Review review=null;
while(iterator.hasNext()){
DocumentReference documentReference1=iterator.next();
ApiFuture<DocumentSnapshot> future= documentReference1.get();
DocumentSnapshot document=future.get();
review=document.toObject(Review.class);
reviewList.add(review);
}
return reviewList;
}
public String updateReview(Review review) throws ExecutionException, InterruptedException {
Firestore dbFirestore= FirestoreClient.getFirestore();
ApiFuture<WriteResult> collectionApiFuture=dbFirestore.collection(COLLECTION_NAME).document(review.getName()).set(review);
return collectionApiFuture.get().getUpdateTime().toString();
}
public String deleteReview(String name) throws ExecutionException, InterruptedException {
Firestore dbFirestore= FirestoreClient.getFirestore();
ApiFuture<WriteResult> collectionApiFuture=dbFirestore.collection(COLLECTION_NAME).document(name).delete();
return "Document with Review ID " name " has been deleted successfully";
}
}
This is my Entity Class
package com.example.firebase.springbootfirebasedemo.entity;
public class Review {
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
This is a class which reads the google service account key
package com.example.firebase.springbootfirebasedemo.firebase;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@Service
public class FirebaseInitialization {
@PostConstruct
public void initialization(){
FileInputStream serviceAccount = null;
try {
serviceAccount = new FileInputStream("./serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is my 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.example.firebase</groupId>
<artifactId>springboot-firebase-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-firebase-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.firebase/firebase-admin-->
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>7.1.0</version>
</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>
</plugins>
</build>
</project>
Till here I was able to call my REST API and perform CRUD operations on my Firestore DB. Now i need to call the Google cloud storage API from my Firebase API. For this i added the Google Cloud Storage dependencies.
My new pom.xml after adding the Google cloud storage dependencies.My new pom.xml after adding the Google cloud storage dependencies.
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.example.firebase</groupId>
<artifactId>springboot-firebase-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-firebase-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud-gcp.version>2.0.4</spring-cloud-gcp.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-storage</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.firebase/firebase-admin -->
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>${spring-cloud-gcp.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Мой файл application.properties
gcs-resource-test-bucket=gcpfirebase
spring.cloud.gcp.project-id = lustrous-braid-326814
spring.cloud.gcp.credentials.location=file:D:\Downloads\Eclipse\keys\serviceAccountKey.json
Теперь после добавления зависимостей и запуска сервера я получал следующие ошибки.
:: Spring Boot :: (v2.5.5)
2021-09-30 17:49:33.339 INFO 9044 --- [ main] .e.f.s.SpringbootFirebaseDemoApplication : Starting SpringbootFirebaseDemoApplication using Java 15.0.2 on DELL-PC with PID 9044 (D:DownloadsEclipseeclipse-workspacespringboot-firebase-movie-reviewtargetclasses started by User in D:DownloadsEclipseeclipse-workspacespringboot-firebase-movie-review)
2021-09-30 17:49:33.344 INFO 9044 --- [ main] .e.f.s.SpringbootFirebaseDemoApplication : No active profile set, falling back to default profiles: default
2021-09-30 17:49:34.924 ERROR 9044 --- [ main] o.a.catalina.core.AprLifecycleListener : An incompatible version [1.1.17-dev] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.14]
2021-09-30 17:49:35.441 INFO 9044 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-09-30 17:49:35.460 INFO 9044 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-09-30 17:49:35.460 INFO 9044 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.53]
2021-09-30 17:49:35.657 INFO 9044 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-09-30 17:49:35.657 INFO 9044 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2156 ms
2021-09-30 17:49:36.380 INFO 9044 --- [ main] c.g.c.s.core.DefaultCredentialsProvider : Default credentials provider for service account firebase-adminsdk-a6cts@lustrous-braid-326814.iam.gserviceaccount.com
2021-09-30 17:49:36.380 INFO 9044 --- [ main] c.g.c.s.core.DefaultCredentialsProvider : Scopes in use by default credentials: [https://www.googleapis.com/auth/pubsub, https://www.googleapis.com/auth/spanner.admin, https://www.googleapis.com/auth/spanner.data, https://www.googleapis.com/auth/datastore, https://www.googleapis.com/auth/sqlservice.admin, https://www.googleapis.com/auth/devstorage.read_only, https://www.googleapis.com/auth/devstorage.read_write, https://www.googleapis.com/auth/cloudruntimeconfig, https://www.googleapis.com/auth/trace.append, https://www.googleapis.com/auth/cloud-platform, https://www.googleapis.com/auth/cloud-vision, https://www.googleapis.com/auth/bigquery, https://www.googleapis.com/auth/monitoring.write]
2021-09-30 17:49:36.382 INFO 9044 --- [ main] c.g.c.s.a.c.GcpContextAutoConfiguration : The default project ID is lustrous-braid-326814
2021-09-30 17:49:37.827 WARN 9044 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'storage' defined in class path resource [com/google/cloud/spring/autoconfigure/storage/GcpStorageAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.google.cloud.storage.Storage]: Factory method 'storage' threw exception; nested exception is java.lang.ExceptionInInitializerError
2021-09-30 17:49:37.841 INFO 9044 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-09-30 17:49:37.864 INFO 9044 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-09-30 17:49:37.892 ERROR 9044 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'storage' defined in class path resource [com/google/cloud/spring/autoconfigure/storage/GcpStorageAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.google.cloud.storage.Storage]: Factory method 'storage' threw exception; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.10.jar:5.3.10]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.10.jar:5.3.10]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.5.jar:2.5.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.5.jar:2.5.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.5.jar:2.5.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.5.jar:2.5.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.5.jar:2.5.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.5.jar:2.5.5]
at com.example.firebase.springbootfirebasedemo.SpringbootFirebaseDemoApplication.main(SpringbootFirebaseDemoApplication.java:10) ~[classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.google.cloud.storage.Storage]: Factory method 'storage' threw exception; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.10.jar:5.3.10]
... 19 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null
at com.google.api.services.storage.Storage$Builder.build(Storage.java:11194) ~[google-api-services-storage-v1-rev20210127-1.32.1.jar:na]
at com.google.cloud.storage.spi.v1.HttpStorageRpc.<init>(HttpStorageRpc.java:122) ~[google-cloud-storage-1.118.0.jar:1.118.0]
at com.google.cloud.storage.StorageOptions$DefaultStorageRpcFactory.create(StorageOptions.java:55) ~[google-cloud-storage-1.118.0.jar:1.118.0]
at com.google.cloud.storage.StorageOptions$DefaultStorageRpcFactory.create(StorageOptions.java:49) ~[google-cloud-storage-1.118.0.jar:1.118.0]
at com.google.cloud.ServiceOptions.getRpc(ServiceOptions.java:560) ~[google-cloud-core-1.95.4.jar:1.95.4]
at com.google.cloud.storage.StorageOptions.getStorageRpcV1(StorageOptions.java:121) ~[google-cloud-storage-1.118.0.jar:1.118.0]
at com.google.cloud.storage.StorageImpl.<init>(StorageImpl.java:124) ~[google-cloud-storage-1.118.0.jar:1.118.0]
at com.google.cloud.storage.StorageOptions$DefaultStorageFactory.create(StorageOptions.java:45) ~[google-cloud-storage-1.118.0.jar:1.118.0]
at com.google.cloud.storage.StorageOptions$DefaultStorageFactory.create(StorageOptions.java:39) ~[google-cloud-storage-1.118.0.jar:1.118.0]
at com.google.cloud.ServiceOptions.getService(ServiceOptions.java:540) ~[google-cloud-core-1.95.4.jar:1.95.4]
at com.google.cloud.spring.autoconfigure.storage.GcpStorageAutoConfiguration.storage(GcpStorageAutoConfiguration.java:86) ~[spring-cloud-gcp-autoconfigure-2.0.4.jar:2.0.4]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.10.jar:5.3.10]
... 20 common frames omitted
Caused by: java.lang.IllegalStateException: You are currently running with version 1.30.10 of google-api-client. You need at least version 1.31.1 of google-api-client to run version 1.32.1 of the Cloud Storage JSON API library.
at com.google.common.base.Preconditions.checkState(Preconditions.java:534) ~[guava-30.1.1-jre.jar:na]
at com.google.api.client.util.Preconditions.checkState(Preconditions.java:113) ~[google-http-client-1.39.2.jar:1.39.2]
at com.google.api.services.storage.Storage.<clinit>(Storage.java:44) ~[google-api-services-storage-v1-rev20210127-1.32.1.jar:na]
... 36 common frames omitted
Пожалуйста, помогите. Спасибо.
Комментарии:
1. Вы действительно прочитали ошибку или только запаниковали?
Caused by: java.lang.IllegalStateException: You are currently running with version 1.30.10 of google-api-client. You need at least version 1.31.1 of google-api-client to run version 1.32.1 of the Cloud Storage JSON API library.
это сообщение об ошибке выглядит для меня довольно ясным. Вам нужна более новая версия GCP.