How to save data to Firebase using Java (Desktop)

被刻印的时光 ゝ 提交于 2020-01-13 07:11:50

问题


I'm trying to save data to Firebase using a desktop application written in Java. However, for some reason it doesn't work, I've been folowing the documentation provided here: https://firebase.google.com/docs/database/admin/save-data. Couldn't find any video tutorials on the matter, all videos are web or mobile related. Basically I want to create an object called Venda that has 3 attributes (ID, data, valor) and then save it on Firebase. Thank you!

Here is the main method:

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 connection:

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();
    }

}

Venda class:

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;
    }

}

The database info:

For now the rules are set to public, for testing purposes.


UPDATE:

Alright after trying what was proposed on FrankvanPuffelen's comment I'm still not able to save or read data from Firebase. I made a simpler code for testing purposes. Here is the code:

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();

}

}

So what I've been doing is, I run the code and then go to the database url and manually edit a post, I expect to get a print of the post I just edited on the console, but nothing happens.

Here is a snapshot of the database:


UPDATE 2

I believe what was proposed here: Why Firebase Java SDK can't terminate after set? is deprecated, because if I try the code looks like this:

I tried modifying that to this:

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();
}

But the onComplete method never gets executed and the programs never finishes. As for what was proposed here: java Firebase: delay exit until writes finish may also be deprecated as it seems the CompletionListener() no longer lives inside Firebase, but I could find it inside DatabaseReference, so I modified the code to this:

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());
}

Like before, the onComplete method never gets executed and the program never finishes or set the data in the database. Here is a snapshot of the post I'm trying to modify:


UPDATE 3

So I've simplified the code for ease of use. Just to be sure I generated a new private key from the project's service account pannel, here is how I initialize the app:

    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);
    }

Here is a snapshot of the database, the value I'm trying to change is the author field of post with id "adad2131".

I've tried referencing that field with "posts/adad2131/author", "/posts/adad2131/author" or simply "adad2131/author", maybe I'm referencing it wrong?

Here is the full code:

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();

    }
}

Ps. I'm also using admin sdk 5.9


回答1:


I just copied your code into a project using Firebase Admin SDK 5.9 and ran it, and it wrote to the database without problems.

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();

You can see the result here: https://stackoverflow.firebaseio.com/49723347.json

The reference 49723347 is the path in my database (it's the ID of your question). I made no other changes.

So it seems that the problem is not in the code we've been looking at. Here's how I initialize the app:

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);

Are you sure the configuration is for the project you're trying to write?



来源:https://stackoverflow.com/questions/49723347/how-to-save-data-to-firebase-using-java-desktop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!