Java Firebase 身份验证在 IDE (Eclipse) 中有效,但在发布时无效

问题描述 投票:0回答:1

我正在开发一个用于内部文档的小型 Java 工具,该工具将数据上传到 Google Firestore 数据库,而另一个内部 Web 应用程序则读取该数据。因此,意识到这种情况的风险有限,我决定使用服务帐户登录 Firebase 进行上传部分:我从云控制台下载了 JSON 身份验证文件,并将其复制到要执行的执行路径中。通过Java代码读取。
当我在 Eclipse 上进行开发时,一切工作正常:数据发送时没有错误或问题,并且我可以从其他 Web 应用程序读取数据。但是,当我编译该工具并将其导出为可运行的 jar 时,数据上传失败:堆栈跟踪的看似相关的位是这样的:

com.google.api.gax.rpc.UnavailableException:io.grpc.StatusRuntimeException:UNAVAILABLE:凭据无法获取元数据
[...]
导致:io.grpc.StatusRuntimeException:不可用:凭证无法获取元数据
[...]
原因:com.google.auth.oauth2.GoogleAuthException:获取服务帐户的访问令牌时出错:收到致命警报:handshake_failure,iss:[我的服务帐户邮件]

我读到这可能是由系统时间引起的,但就我而言,在我用来测试它的每台计算机上时间都很好,而且主要是即使在我开发该工具的同一台机器上也会发生这种情况:在 IDE 中它工作得很好,但在外面,即使使用相同的 JDK(顺便说一句,OpenJDK 16),它也无法登录到 firebase,现在我已经不知道为什么会发生这种情况了。我还检查了 Eclipse 用于运行应用程序的命令行,但是,除了一长串显式依赖项之外,其中似乎没有任何用处:应用程序启动得很好,没有丢失模块或库。此外,IDE 的运行配置中没有设置其他选项,例如环境变量或命令行参数,这些选项在其他环境中可能会丢失。我希望有人能给我一些关于如何阐明这一点的想法。

这是执行身份验证的代码,无论在 IDE 内还是在 IDE 外运行都不会出现错误:

  private static Firestore getFirestoreInstance() {
        if (firestoreDbInstance != null) {
           return firestoreDbInstance;
        }
        InputStream serviceAccountFile;
        try {
            serviceAccountFile = new FileInputStream(/*path to the credentials file*/);
        } catch (FileNotFoundException e) { 
            writeExceptionToLog(e);
            return null;
        }
        GoogleCredentials credentials;
        try {
            credentials = GoogleCredentials.fromStream(serviceAccountFile);

            FirebaseOptions options = FirebaseOptions.builder().setCredentials(credentials)
                    .setProjectId(APIConstants.projectId).build();

            FirebaseApp.initializeApp(options);

            firestoreDbInstance = FirestoreClient.getFirestore();

            return firestoreDbInstance;
        } catch (IOException e) {
            writeToLog("Error getting firestore instance");
            writeExceptionToLog(e);
        }
        return null;

    }

这是上传数据的方法之一:错误似乎发生在这里,因为在堆栈跟踪中存在对

onFailure
的引用,但我认为问题不在这里,因为异常引用了凭据:

    Firestore db = getFirestoreInstance();

    UUID uuid = UUID.randomUUID();

    DocumentReference docRef = db.collection(APIConstants.pendingRequestsCollection).document(uuid.toString());
   
    Map<String, Object> data = new HashMap<>();
    [...adding JSON data...]
    ApiFuture<WriteResult> result = docRef.set(data);

    ApiFutures.addCallback(result, new ApiFutureCallback<WriteResult>() {
        @Override
        public void onFailure(Throwable throwable) {
            [...showing dialog with error...]
            writeExceptionToLog(throwable);
        }

        @Override
        public void onSuccess(WriteResult writeResult) {
            writeToLog("Upload successful: " + uuid.toString());

        }
    }, Runnable::run);

主要问题是:这种不同行为的原因可能是什么?相同的 jdk、文件中相同的数据、相同的包...如果我在 Eclipse 中运行它,一切都很好,但是当我尝试运行编译的 JAR 文件时,上传失败并出现该错误。

相关版本
Eclipse 版本 2023-12 (4.30.0)
Maven com.google.firebase,firebase-admin,9.2.0

java firebase eclipse
1个回答
0
投票

我找到了一个解决方法:我使用了同一依赖项中的另一个类(按照here找到的提示),并使用

FirestoreOptions
而不是
FirebaseOptions

            credentials = GoogleCredentials.fromStream(serviceAccountFile);
            FirestoreOptions bis = FirestoreOptions.newBuilder()
                    .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
                    .setProjectId(APIConstants.projectId).build();
            //no need to initialize an app now
            firestoreDbInstance = bis.getService();

令我惊讶的是,该工具现在可以在 Eclipse 内和外运行:我的问题现在已经解决,但我仍然不知道为什么会发生这种情况。我不会回答这个问题,以防有人提出想法。

© www.soinside.com 2019 - 2024. All rights reserved.