如何使用Java(桌面)将数据保存到Firebase

时间:2018-04-08 22:25:55

标签: java firebase firebase-realtime-database

我正在尝试使用Java编写的桌面应用程序将数据保存到Firebase。但是,由于某种原因,它不起作用,我已经在这里提供了文档:https://firebase.google.com/docs/database/admin/save-data。无法找到有关此事的任何视频教程,所有视频都与网络或移动相关。基本上我想创建一个名为Venda的对象,它有3个属性(ID,数据,valor),然后将其保存在Firebase上。谢谢!

这是主要方法:

public class Main {

    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println("--------- Begin of Output ---------");
        Firebase firebase = new Firebase();
        VendasCRUD venda = new VendasCRUD(firebase);
        venda.createVenda(new Venda(0, "23/05/1993", 45.67));
        System.out.println("----------- End of Output -----------");
    }

}

Firebase连接:

public class Firebase {

    public Firebase() throws FileNotFoundException, IOException {
        FileInputStream serviceAccount = new FileInputStream("C:\\Users\\Alex\\Documents\\NetBeansProjects\\SEMS\\src\\main\\java\\br\\com\\sems\\firebase\\sems-firebase.json");

        FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                .setDatabaseUrl("https://sems-firebase.firebaseio.com/")
                .build();

        FirebaseApp.initializeApp(options);
    }

    public DatabaseReference getDataBaseReference() {
        return FirebaseDatabase.getInstance().getReference();
    }

}

文达班:

public class Venda {

    public int ID;
    public String data;
    public double valor;

    public Venda(int ID, String data, double valor) {
        this.ID = ID;
        this.data = data;
        this.valor = valor;
    }

    @Override
    public String toString() {
        return ID + "," + data + "," + valor;
    }

}

数据库信息:

enter image description here

目前,为了测试目的,规则已设置为公开。

更新:

在尝试了FrankvanPuffelen的评论之后,我还是无法保存或读取Firebase中的数据。我为测试目的制作了一个更简单的代码。这是代码:

public class Main {

    private static final String DATABASE_URL = "https://sems-firebase.firebaseio.com/";
    private static DatabaseReference database;
    private static boolean finished = false;

    public static void startListeners() {
        database.child("posts").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Post post = dataSnapshot.getValue(Post.class);
                System.out.println(post);
                finished = true;
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("The read failed: " + databaseError.getCode());
            }
        });
        while(!finished);
    }

    public static void main(String[] args) throws FileNotFoundException {

        try {
            FileInputStream serviceAccount = new FileInputStream("sems-firebase.json");
            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                    .setDatabaseUrl(DATABASE_URL)
                    .build();



        FirebaseApp defaultApp =  FirebaseApp.initializeApp(options);
        FirebaseDatabase defaultDatabase = FirebaseDatabase.getInstance(defaultApp);

        System.out.println(defaultDatabase.getReference().toString());

    } catch (IOException e) {
        System.out.println("ERROR: invalid service account credentials. See README.");
        System.out.println(e.getMessage());

        System.exit(1);
    }

    // Shared Database reference
    database = FirebaseDatabase.getInstance().getReference();

    // Start listening to the Database
    startListeners();

}

}

所以我一直在做的是,我运行代码,然后转到数据库网址并手动编辑帖子,我希望得到我刚刚在控制台上编辑的帖子的打印,但没有任何反应

以下是数据库的快照: enter image description here

更新2

我相信这里提出的内容:Why Firebase Java SDK can't terminate after set?已被弃用,因为如果我尝试代码看起来像这样:

enter image description here

我尝试修改它:

public static void startListeners() throws InterruptedException {
    DatabaseReference database = FirebaseDatabase.getInstance().getReference("posts/adad2131/author");
    CountDownLatch done = new CountDownLatch(1);
    database.setValue("Test", new DatabaseReference.CompletionListener() {
        @Override
        public void onComplete(DatabaseError de, DatabaseReference dr) {
            done.countDown();
        }
    });
    done.await();
}

但onComplete方法永远不会被执行,程序永远不会完成。至于这里提出的内容:java Firebase: delay exit until writes finish也可能已被弃用,因为似乎CompletionListener()不再存在于Firebase中,但我可以在DatabaseReference中找到它,所以我将代码修改为:

private static final String DATABASE_URL = "https://sems-firebase.firebaseio.com/";

public static void startListeners() throws InterruptedException {
    DatabaseReference database = FirebaseDatabase.getInstance().getReference("posts/adad2131/author");
    final AtomicBoolean done = new AtomicBoolean(false);
    database.setValue("Test", new DatabaseReference.CompletionListener() {
        @Override
        public void onComplete(DatabaseError de, DatabaseReference dr) {
            done.set(true);
        }
    });
    while (!done.get());
}

与之前一样,onComplete方法永远不会被执行,程序永远不会完成或设置数据库中的数据。以下是我试图修改的帖子的快照:

enter image description here

更新3

所以我简化了易用性代码。为了确保我从项目的服务帐户面板生成了一个新的私钥,以下是我初始化应用程序的方法:

    try {
        FileInputStream serviceAccount = new FileInputStream("sems-firebase-firebase-adminsdk-gamnp-874087bbd1.json");
        FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                .setDatabaseUrl("https://sems-firebase.firebaseio.com/")
                .build();

        FirebaseApp.initializeApp(options);

    } catch (IOException e) {
        System.out.println("ERROR: invalid service account credentials.");
        System.out.println(e.getMessage());

        System.exit(1);
    }

以下是数据库的快照,我尝试更改的值是带有ID" adad2131"的帖子的作者字段。

enter image description here

我尝试使用" posts / adad2131 / author"," / posts / adad2131 / author"引用该字段。或者只是" adad2131 / author",也许我引用它错了?

以下是完整代码:

public class Main {

    public static void main(String[] args) throws FileNotFoundException, InterruptedException {

        try {
            FileInputStream serviceAccount = new FileInputStream("sems-firebase-firebase-adminsdk-gamnp-874087bbd1.json");
            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                    .setDatabaseUrl("https://sems-firebase.firebaseio.com/")
                    .build();

            FirebaseApp.initializeApp(options);

        } catch (IOException e) {
            System.out.println("ERROR: invalid service account credentials.");
            System.out.println(e.getMessage());

            System.exit(1);
        }

        //Try to change data in Firebase
        CountDownLatch done = new CountDownLatch(1);
        FirebaseDatabase.getInstance().getReference("posts/adad2131/author").setValue("Test", new DatabaseReference.CompletionListener() {
            @Override
            public void onComplete(DatabaseError de, DatabaseReference dr) {
                done.countDown();
            }
        });
        done.await();

    }
}

聚苯乙烯。我还使用了admin sdk 5.9

1 个答案:

答案 0 :(得分:1)

我刚刚使用Firebase Admin SDK 5.9将您的代码复制到一个项目中并运行它,并且它没有问题地写入数据库。

CountDownLatch done = new CountDownLatch(1);
FirebaseDatabase.getInstance().getReference("49723347").setValue("Test", new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError de, DatabaseReference dr) {
        done.countDown();
    }
});
done.await();

您可以在此处查看结果:https://stackoverflow.firebaseio.com/49723347.json

引用49723347是我数据库中的路径(它是您问题的ID)。我没有做任何其他改变。

所以似乎问题不在于我们一直在关注的代码中。这是我初始化应用程序的方式:

FileInputStream serviceAccount = new FileInputStream("stackoverflow-3d9889aaeddb.json");

FirebaseOptions options = new FirebaseOptions.Builder()
        .setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
        .setDatabaseUrl("https://stackoverflow.firebaseio.com/")
        .build();

FirebaseApp.initializeApp(options);

您确定配置是针对您尝试编写的项目吗?