Я пытаюсь сохранить данные в Firebase с помощью настольного приложения, написанного на Java. Однако по какой-то причине это не работает, я следил за документацией, представленной здесь: https://firebase.google.com/docs/database/admin/save-data. Не удалось найти никаких видеоуроков по этому вопросу, все видео относятся к веб-сайтам или мобильным устройствам. В основном я хочу создать объект под названием Venda, который имеет 3 атрибута (идентификатор, данные, доблесть), а затем сохранить его в 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;
}
}
Информация о базе данных:
На данный момент правила являются общедоступными для целей тестирования.
ОБНОВИТЬ:
Хорошо, попробовав то, что было предложено в комментарии 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();
}
}
Итак, что я делал, я запускаю код, а затем перехожу к URL-адресу базы данных и вручную редактирую сообщение, я ожидаю получить печать сообщения, которое я только что редактировал на консоли, но ничего не происходит.
ОБНОВЛЕНИЕ 2
Я считаю, что здесь было предложено: Почему Firebase Java SDK не может завершиться после установки? устарел, потому что, если я попробую, код будет выглядеть так:
Я попытался изменить это на это:
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: отложить выход до завершения записи также может быть устаревшим, поскольку кажется, что 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 никогда не запускается, и программа никогда не завершает работу и не устанавливает данные в базе данных. Вот снимок сообщения, которое я пытаюсь изменить:
ОБНОВЛЕНИЕ 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);
}
Вот снимок базы данных, значение, которое я пытаюсь изменить, - это поле автора сообщения с идентификатором «adad2131».
Я пробовал ссылаться на это поле с помощью «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
Примеры: stackoverflow.com/questions/45253891/…, stackoverflow.com/questions/26092632/…, groups.google.com/forum/#!searchin/firebase-talk/exit$20java /….
Как только я вернусь домой, я посмотрю на ссылку, которую вы разместили, и дам отзыв, спасибо.
Итак, я прочитал ответы и попробовал оба предложенных решения. Первый действительно остановил программу, но так и не установил данные и не завершил программу. Для второго он использует Firebase.CompletionListener () из com.firebase.client.Firebase; однако по какой-то причине maven не может найти эту зависимость. Третья ссылка, которую я не смог открыть. Как вы думаете, что-то не так с тем, как я пытаюсь вставить в базу данных?
Я нашел CompletionListener () внутри DatabaseReference вместо Firebase, но он все еще не записывал в базу данных. Я начинаю задаваться вопросом, не что-то не так со ссылкой на мою базу данных.
@FrankvanPuffelen
Не видя обновленного кода, трудно понять, что происходит.
Позвольте нам продолжить обсуждение в чате.
@FrankvanPuffelen Я добавил обновленный код, вы можете мне помочь? Мне действительно нужно, чтобы это работало. Спасибо за вашу помощь.
Вы делаете плотная петля, что сильно отличается от того, что делают ссылки, которые я предоставил. Я действительно не могу сделать его намного короче, чем то, что я показал здесь: stackoverflow.com/a/45256059 или то, что Като показал здесь: stackoverflow.com/a/26112036.
@FrankvanPuffelen, спасибо за ваш вклад, на самом деле я пробовал то, что было предложено в этих сообщениях, но, поскольку это не сработало, я решил не публиковать свой код для этого. Но на данный момент я добавил раздел UPDATE 2 с кодом для обеих этих попыток.




Я просто скопировал ваш код в проект с помощью 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 - это путь в моей базе данных (это идентификатор вашего вопроса). Других изменений я не делал.
Так что, похоже, проблема не в коде, который мы рассматривали. Вот как я инициализирую приложение:
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);
Вы уверены, что конфигурация соответствует проекту, который вы пытаетесь написать?
Моя единственная подсказка заключается в том, что я мог неправильно ссылаться на поле автора, я добавил раздел ОБНОВЛЕНИЕ 3, показывающий, что я сделал.
Для меня это в основном то же самое. Вы уверены, что перейдете на звонок setValue? Если вы запустите отладчик и установите точку останова на этой строке, сработает ли он?
Я так и сделал, точка останова в строке setValue () действительно срабатывает, затем выполняет done.await () и никогда не завершается, потому что onComplete () никогда не запускается. Я попытался также установить точку останова на onComplete (), и вот результат Listening on 55920 User program running Not able to submit breakpoint LineBreakpoint Main.java : 38, reason: No executable location available at line 38 in class br.com.firebasetest.Main$1. Invalid LineBreakpoint Main.java : 38
Есть ли какие-то дополнительные настройки, которые нужно сделать в самом проекте?
Как вы думаете, связано ли это с тем, что на панели управления Firebase нет настроенного приложения? Раньше я использовал базу данных реального времени для приложения iOS, и у меня не было никаких проблем. Но там есть только варианты настройки веб-приложений, приложений для Android и iOS, а для настольных приложений Java нет. Хотите попробовать ввести данные прямо в мою базу данных? Я могу дать вам закрытый ключ json, в любом случае это просто тестовая база данных.
Я только что проверил, и у меня нет приложения для моего проекта администратора. Так что я сомневаюсь, что это имеет значение.
Как вы думаете, мне следует обратиться в службу поддержки Firebase, чтобы решить эту проблему? Они говорят, что их поддержка не распространяется на код, поэтому, если мне нужна поддержка по коду, я должен опубликовать его на Stackoverfkow. Поскольку я сделал именно это, а моя программа все еще не работает, это мое последнее средство.
Я очень сомневаюсь, что ваш проект прерван, поэтому служба поддержки, скорее всего, сделает то же самое, что и я: попытается добраться до MCVE. С другой стороны: может быть, кто-то там видит что-то, чего нам обоим не хватало. Обязательно указывайте на эту тему, когда открываете дело, потому что мои тесты показали, что проблема не в конкретном фрагменте кода. Это также может быть хорошим моментом, чтобы урезать ваш вопрос: проблема не должна нуждаться в большем количестве кода, чем то, что я использовал. Поскольку вы видите поведение, отличное от того, что я вижу с этим кодом, код кажется нормальным.
Хорошо, я открою билет позже, следуя вашим инструкциям. Большое спасибо за ваше время и терпение. Как только у меня будет ответ, я отправлю его сюда.
Фрэнк, в документы говорится, что «Java SDK Firebase Admin опубликован в центральном репозитории Maven. Чтобы установить библиотеку, объявите ее как зависимость в вашем файле build.gradle» dependencies { compile 'com.google.firebase:firebase-admin:5.9.0' } Я никогда этого не делал, я только добавил <dependency> <groupId>com.google.firebase</groupId> <artifactId>firebase-admin</artifactId> <version>5.9.0</version> </dependency> в мой файл pom.xml. Также я попытался изменить значение в базе данных, которое, как я знаю, работает, поэтому проблема не в БД.
Итак, я думаю, что это сужает его до некоторой конфигурации на моем локальном компьютере, есть идеи?
Скорее всего, ваша программа Java завершится до того, как Firebase сможет записать данные. Типичные решения - добавить задержку (очень просто) или использовать семафор, чтобы сигнализировать о завершении записи (намного лучше). Позвольте мне найти вопрос, для которого уже есть образцы.