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