Получить ссылку на документ перед добавлением данных в коллекцию в Firestore - PullRequest
0 голосов
/ 26 апреля 2018

Я борюсь с Firestore, потому что не хватает документации, которая может описать все возможные сценарии работы Firestore.

Позвольте мне объяснить мои требования.

У меня есть следующий графический интерфейсв андроиде:

  • EditText.(Имя)
  • Спиннер.(города)
  • Спиннер.(Автобусы)
  • Кнопка добавления

В Firestore имеются следующие коллекции:

  • города (содержащие несколько городов)
  • busses (которые содержат несколько шин)
  • user (который будет содержать имя пользователя, ссылку на шину, ссылку на город)

Теперь проблема заключается в том, что когда пользователь нажимает на кнопку AddКнопка, сначала я должен получить ссылку на selected city и selected bus, затем добавить эти три значения в коллекцию user, но чтобы получить ссылку, я должен вызвать следующий код.

final Map<String, Object> data = new HashMap<>();
        data.put("username", editText.getText().toString());

        db.collection("cities")
        .whereEqualTo("name", city) // get city by name
        .get()
        .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
            @Override
            public void onSuccess(QuerySnapshot query) {
                data.put("city", query.getDocuments().get(0).getReference());
                // once the city reference got, then get the Buss reference
                db.collection("busses")
                .whereEqualTo("busnumber", bus) // get bus by number
                .get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot query) {
                        data.put("bus", query.getDocuments().get(0).getReference());
                        addData(data); // now the city and bus reference got, add the data now.
                    }
                });
            }
        });

Это делает приложение немного медленным и выглядит глупо, я хочу подтвердить, что это правильный подход?или есть лучший способ сделать это?или в будущем, возможно, мне придется получить больше ссылок, чем больше вложенных вызовов?

Отредактировано

Более того, это действительно глупый способ вспомнить эти кодыснова и снова, чтобы получить ссылку city или bus, поэтому в моем приложении будет много дублирования, что не очень хорошо.Поэтому я хочу создать два метода getCityRefByName(String name) и getBusRefByNUmber(int number) следующим образом.

public DocumentReference getBusByNumber(int number){
    db.collection("busses")
    .whereEqualTo("busname", number)
    .get()
    .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot query) {
            query.getDocuments().get(0).getReference(); // return this reference, How?
        }
    });
}

public DocumentReference getCityRefByName(String name){
    db.collection("cities")
    .whereEqualTo("name", name)
    .get()
    .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot query) {
            query.getDocuments().get(0).getReference(); // return this reference, How?
        }
    });
}

Документация Firestore недостаточно хороша, поэтому я сталкиваюсь с этими глупыми проблемами с ядром.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

вернуть эту ссылку, как?

Вы не можете вернуть то, что еще не было загружено.Другими словами, вы не можете просто использовать этот результат вне метода onSuccess(), потому что он всегда будет null из-за асинхронного поведения этого метода.Это означает, что к тому времени, когда вы пытаетесь использовать этот результат вне этого метода, данные еще не закончили загрузку из базы данных, и поэтому они недоступны.Для быстрого решения этой проблемы было бы использовать эти результаты только внутри метода onSuccess(), в противном случае я рекомендую вам увидеть последнюю часть моего ответа из этого поста , в котором я имеюобъяснил, как это можно сделать с помощью специального обратного вызоваВы также можете взглянуть на это видео для лучшего понимания.

0 голосов
/ 26 апреля 2018

Я думаю, вы должны запустить методы, чтобы собрать City и Bus вместе, вот так

private boolean gotCity, gotBus;
private void run() {
    final Map<String, Object> data = new HashMap<>();
    data.put("username", editText.getText().toString());
    gotBus= false;
    gotCity = false;
    db.collection("cities")
            .whereEqualTo("name", city) // get city by name
            .get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot query) {
                    data.put("city", query.getDocuments().get(0).getReference());
                    // once the city reference got, then get the Buss reference
                    gotCity = true;
                    if(gotCity&& gotBus)  addData(data); // now the city and bus reference got, add the data now.
                }
            });
    db.collection("busses")
            .whereEqualTo("busnumber", bus) // get bus by number
            .get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot query) {
                    data.put("bus", query.getDocuments().get(0).getReference());
                    gotBus = true;
                    if(gotCity&& gotBus)  addData(data); // now the city and bus reference got, add the data now.
                }
            });

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...