Как сохранить данные в Firebase с помощью Java (Desktop)

Я пытаюсь сохранить данные в 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;
    }

}

Информация о базе данных:

Как сохранить данные в Firebase с помощью Java (Desktop)

На данный момент правила являются общедоступными для целей тестирования.


ОБНОВИТЬ:

Хорошо, попробовав то, что было предложено в комментарии 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-адресу базы данных и вручную редактирую сообщение, я ожидаю получить печать сообщения, которое я только что редактировал на консоли, но ничего не происходит.

Вот снимок базы данных: Как сохранить данные в Firebase с помощью Java (Desktop)


ОБНОВЛЕНИЕ 2

Я считаю, что здесь было предложено: Почему Firebase Java SDK не может завершиться после установки? устарел, потому что, если я попробую, код будет выглядеть так:

Как сохранить данные в Firebase с помощью Java (Desktop)

Я попытался изменить это на это:

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 никогда не запускается, и программа никогда не завершает работу и не устанавливает данные в базе данных. Вот снимок сообщения, которое я пытаюсь изменить:

Как сохранить данные в Firebase с помощью Java (Desktop)


ОБНОВЛЕНИЕ 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».

Как сохранить данные в Firebase с помощью Java (Desktop)

Я пробовал ссылаться на это поле с помощью «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

Скорее всего, ваша программа Java завершится до того, как Firebase сможет записать данные. Типичные решения - добавить задержку (очень просто) или использовать семафор, чтобы сигнализировать о завершении записи (намного лучше). Позвольте мне найти вопрос, для которого уже есть образцы.

Frank van Puffelen 09.04.2018 00:53

Как только я вернусь домой, я посмотрю на ссылку, которую вы разместили, и дам отзыв, спасибо.

Alexandre Krabbe 09.04.2018 00:58

Итак, я прочитал ответы и попробовал оба предложенных решения. Первый действительно остановил программу, но так и не установил данные и не завершил программу. Для второго он использует Firebase.CompletionListener () из com.firebase.client.Firebase; однако по какой-то причине maven не может найти эту зависимость. Третья ссылка, которую я не смог открыть. Как вы думаете, что-то не так с тем, как я пытаюсь вставить в базу данных?

Alexandre Krabbe 09.04.2018 03:16

Я нашел CompletionListener () внутри DatabaseReference вместо Firebase, но он все еще не записывал в базу данных. Я начинаю задаваться вопросом, не что-то не так со ссылкой на мою базу данных.

Alexandre Krabbe 09.04.2018 03:38

@FrankvanPuffelen

Alexandre Krabbe 09.04.2018 20:20

Не видя обновленного кода, трудно понять, что происходит.

Frank van Puffelen 09.04.2018 21:47

Позвольте нам продолжить обсуждение в чате.

Alexandre Krabbe 10.04.2018 02:14

@FrankvanPuffelen Я добавил обновленный код, вы можете мне помочь? Мне действительно нужно, чтобы это работало. Спасибо за вашу помощь.

Alexandre Krabbe 10.04.2018 02:16

Вы делаете плотная петля, что сильно отличается от того, что делают ссылки, которые я предоставил. Я действительно не могу сделать его намного короче, чем то, что я показал здесь: stackoverflow.com/a/45256059 или то, что Като показал здесь: stackoverflow.com/a/26112036.

Frank van Puffelen 10.04.2018 02:44

@FrankvanPuffelen, спасибо за ваш вклад, на самом деле я пробовал то, что было предложено в этих сообщениях, но, поскольку это не сработало, я решил не публиковать свой код для этого. Но на данный момент я добавил раздел UPDATE 2 с кодом для обеих этих попыток.

Alexandre Krabbe 10.04.2018 03:12
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
11
5 019
1

Ответы 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 - это путь в моей базе данных (это идентификатор вашего вопроса). Других изменений я не делал.

Так что, похоже, проблема не в коде, который мы рассматривали. Вот как я инициализирую приложение:

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, показывающий, что я сделал.

Alexandre Krabbe 10.04.2018 04:50

Для меня это в основном то же самое. Вы уверены, что перейдете на звонок setValue? Если вы запустите отладчик и установите точку останова на этой строке, сработает ли он?

Frank van Puffelen 10.04.2018 04:53

Я так и сделал, точка останова в строке 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

Alexandre Krabbe 10.04.2018 04:59

Есть ли какие-то дополнительные настройки, которые нужно сделать в самом проекте?

Alexandre Krabbe 10.04.2018 05:00

Как вы думаете, связано ли это с тем, что на панели управления Firebase нет настроенного приложения? Раньше я использовал базу данных реального времени для приложения iOS, и у меня не было никаких проблем. Но там есть только варианты настройки веб-приложений, приложений для Android и iOS, а для настольных приложений Java нет. Хотите попробовать ввести данные прямо в мою базу данных? Я могу дать вам закрытый ключ json, в любом случае это просто тестовая база данных.

Alexandre Krabbe 10.04.2018 18:23

Я только что проверил, и у меня нет приложения для моего проекта администратора. Так что я сомневаюсь, что это имеет значение.

Frank van Puffelen 10.04.2018 18:58

Как вы думаете, мне следует обратиться в службу поддержки Firebase, чтобы решить эту проблему? Они говорят, что их поддержка не распространяется на код, поэтому, если мне нужна поддержка по коду, я должен опубликовать его на Stackoverfkow. Поскольку я сделал именно это, а моя программа все еще не работает, это мое последнее средство.

Alexandre Krabbe 10.04.2018 19:28

Я очень сомневаюсь, что ваш проект прерван, поэтому служба поддержки, скорее всего, сделает то же самое, что и я: попытается добраться до MCVE. С другой стороны: может быть, кто-то там видит что-то, чего нам обоим не хватало. Обязательно указывайте на эту тему, когда открываете дело, потому что мои тесты показали, что проблема не в конкретном фрагменте кода. Это также может быть хорошим моментом, чтобы урезать ваш вопрос: проблема не должна нуждаться в большем количестве кода, чем то, что я использовал. Поскольку вы видите поведение, отличное от того, что я вижу с этим кодом, код кажется нормальным.

Frank van Puffelen 10.04.2018 19:45

Хорошо, я открою билет позже, следуя вашим инструкциям. Большое спасибо за ваше время и терпение. Как только у меня будет ответ, я отправлю его сюда.

Alexandre Krabbe 10.04.2018 19:55

Фрэнк, в документы говорится, что «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. Также я попытался изменить значение в базе данных, которое, как я знаю, работает, поэтому проблема не в БД.

Alexandre Krabbe 10.04.2018 23:57

Итак, я думаю, что это сужает его до некоторой конфигурации на моем локальном компьютере, есть идеи?

Alexandre Krabbe 10.04.2018 23:59

Другие вопросы по теме