【问题标题】:JavaEE and Firebase admin sdk - setValueAsync not pushing data to realtime firebaseJavaEE 和 Firebase admin sdk - setValueAsync 未将数据推送到实时 Firebase
【发布时间】:2023-03-20 12:48:01
【问题描述】:

我在基于 gradle 和 glassfish 服务器的 intellij 上使用 firebase admin sdk 和 JavaEE。

我正在尝试将值推送到实时数据库,但遗憾的是我无法这样做。我已经在网上搜索了几个星期,但什么也没得到。我还在 stackoverflow 答案中遵循了一些解决方案,例如:Firebase Java Admin SDK don't work 但对我没有任何作用。

我已经阅读了很多为什么 firebase admin sdk 会出现此类问题的原因,但我没有解决方案。

这是我的代码:

包装样本;

package sample;

import com.google.api.core.ApiFuture;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseToken;
import com.google.firebase.auth.UserRecord;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import sample.model.FireBaseAuth;
import sample.model.FireBaseUtils;
import sample.model.Owner;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@WebServlet("/success")
public class SuccessServlet extends HttpServlet {

    public void init() throws ServletException {
        super.init();
        FireBaseUtils.initilizeFirebase();
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        String email = request.getParameter("email");
        String password  = request.getParameter("pass");

        //System.out.println(name);

        try{
            //a hashmap for the number of shopsOwned
            HashMap<String, String> shopsOwned = new HashMap<>();
            shopsOwned.put("shopName" , "shopName");

            //get the database instance and the database reference
            FirebaseDatabase database = FirebaseDatabase.getInstance();
            DatabaseReference ref = database.getReference("Business");

            DatabaseReference ownersRef = ref.child("Owners"); //further get the reference to the owners node

            //create a new owner with the values of the new user, using the Owner class
            Owner newOwner = new Owner("userRecord2.getUid()", "userRecord2.getDisplayName()",
                    "userRecord2.getPhoneNumber()", "userRecord2.getEmail()", shopsOwned);

            //create a hashmap of the users, in this case, just one user
            Map<String, Owner> users = new HashMap<>();
            users.put("userRecord2getPhoneNumber", newOwner); //add the new owner to the hashmap

            System.out.println("this is the user :" + newOwner.getFull_name());

            //push the new owner hashmap to the database reference
            ApiFuture<Void> future = ownersRef.push().setValueAsync(users);

            //Object o = future.get(8, TimeUnit.SECONDS);
            System.out.println(future.isDone());
            //System.out.println(future.isDone());

            request.getRequestDispatcher("success.jsp").forward(request, response);

        }catch(Exception e){e.printStackTrace();}



    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        doGet(request, response);

    }

}

任何想法都会受到赞赏。

编辑:我没有收到任何错误,webapp 运行正常,但 firebase 的实时数据库没有更新

【问题讨论】:

  • 运行这段代码有什么问题?你在调试器中单步执行了吗?当你做/做的时候,哪一行没有做你期望它做的事情?
  • 这是行,它没有显示任何错误,但数据永远不会推送到数据库:ApiFuture&lt;Void&gt; future = ownersRef.push().setValueAsync(users); System.out.println(future.isDone()); //这总是返回一个布尔值“false”,表示操作从未成功。
  • 这很可能意味着操作尚未完成,因为它是异步的。您需要添加一个回调来检测写入何时完成,如下所示:medium.com/google-cloud/…

标签: java firebase firebase-realtime-database firebase-admin


【解决方案1】:

你需要等到future完成后,才会返回请求线程。否则无法保证更新完成,任何错误都会被默默丢弃。因此,请尝试以下操作:

ApiFuture<Void> future = ownersRef.push().setValueAsync(users);
future.get();
request.getRequestDispatcher("success.jsp").forward(request, response);

【讨论】:

    【解决方案2】:

    写入 Firestore(如与大多数云 API 的交互)是异步发生的,并且在不同的线程上。当你调用future.isDone()时,操作还没有完成。

    您需要添加一个在操作完成时调用的回调:

    ApiFuture<Void> future = ownersRef.push().setValueAsync(users);
    future.addCallback(future, new ApiFutureCallback<String>() {
        @Override
        public void onSuccess(String result) {
          System.out.println("Operation completed with result: " + result);
          System.out.println(future.isDone());
          request.getRequestDispatcher("success.jsp").forward(request, response);
        }
    
        @Override
        public void onFailure(Throwable t) {
          System.err.println("Operation failed with error: " + t);
        }
    

    另见:

    【讨论】:

    • 我刚刚尝试过,显然,未来的 addCallBack 已被弃用,所以我不得不使用 ApiFutures.addCallBack,无论哪种方式,我仍然没有得到任何响应,系统输出没有任何响应。我什至尝试将执行程序作为第三个参数放在新的 addCallBack 函数中,但没有。没有错误,没有系统输出。
    • 添加回调不会改变事件的流程/时间。你需要“等待”未来,直到它完成。 future.get() 是最简单的解决方案。
    • 嘿@HiranyaJayathilaka。你能用一个例子添加另一个答案吗?将其添加到此处文档中的 sn-p 可能也是一个好主意:firebase.google.com/docs/database/admin/save-data#section-set
    猜你喜欢
    • 1970-01-01
    • 2021-08-28
    • 2020-06-28
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    相关资源
    最近更新 更多