Вложенный Firestore получает используя обратные вызовы, получая пустые результаты при первом вызове - PullRequest
0 голосов
/ 13 мая 2018

Итак, вот мой сценарий: у меня есть три отдельных вызова пожарного магазина в их собственных классах.Все три вызова вложены в обратный вызов друг друга, и в последнем обратном вызове я делаю всю свою работу.Когда я запускаю этот стек, мой объект Admin уже существует, в то время как мой список пользователей и список книг будут создаваться, так как этот стек ожидает обновления.Если данных в базе данных нет, и мы создаем запись, обратный вызов не сообщает о книге (однако я получаю объекты Admin и User).Однако, если мы снова откроем приложение и данные уже существуют в базе данных, обратный вызов сообщит что-то.После этого, когда я добавляю пользователя / книгу, список обновляется корректно.

Примечание: это слушатели в реальном времени, поэтому, как только пользователь / книга будет добавлен, мы увидим обновление.

Вот мои классы:

public class FirebaseGetThisAdmin {

    //firebase objects
    private FirebaseAuth mAuth;
    private FirebaseFirestore mDbase;

    private Activity activity;

    private Admin admin;
    private String adminID;

    //default constructor
    public FirebaseGetThisAdmin() {
    }

    public FirebaseGetThisAdmin(Activity activity) {
        this.activity = activity;
    }

    public interface FirestoreCallback {
        void onCallback(Admin admin);
    }

    public void readDataRTUpdate(final FirestoreCallback firestoreCallback) {

        //firebase new instances
        mAuth = FirebaseAuth.getInstance();
        mDbase = FirebaseFirestore.getInstance();

        //get admin email address and user name from Auth and set textInput fields to them
        if (mAuth.getCurrentUser() != null) {
            adminID = mAuth.getUid();
        }

        final DocumentReference docRef = mDbase.collection("admins").document(adminID);
        docRef.addSnapshotListener(activity, new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(@Nullable DocumentSnapshot snapshot,
                                @Nullable FirebaseFirestoreException e) {
                if (e != null) {
                    Log.w(TAG, "Listen failed.", e);
                    return;
                }

                String source = snapshot != null && snapshot.getMetadata().hasPendingWrites()
                        ? "Local" : "Server";

                if (snapshot != null && snapshot.exists()) {
                    admin = new Admin();
                    admin = snapshot.toObject(Admin.class);
                    //pass variables to the callback
                    firestoreCallback.onCallback(admin);
                    Log.d(TAG, source + " data: " + snapshot.getData());
                } else {
                    Log.d(TAG, source + " data: null");
                }
            }
        });
    }
} 

 public class FirebaseGetUsers {

    //firebase objects
    private FirebaseAuth mAuth;
    private FirebaseFirestore mDbase;

    private Activity activity;

    private String adminID;

    //default constructor
    public FirebaseGetUsers() {
    }

    public FirebaseGetUsers(Activity activity) {
        this.activity = activity;

        //firebase new instances
        mAuth = FirebaseAuth.getInstance();
        mDbase = FirebaseFirestore.getInstance();

        if (mAuth.getCurrentUser() != null) {
            adminID = mAuth.getUid();
        }
    }

    public interface FirestoreCallback {
        void onCallback(List<User> users);
    }

    public void readDataRTUpdate(final FirestoreCallback firestoreCallback) {
        mDbase.collection("admins").document(adminID).collection("users")
                .addSnapshotListener(activity, new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot value,
                                        @Nullable FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.w(TAG, "Listen failed.", e);
                            return;
                        }
                        if (value != null) {
                            int i = 0;
                            List<User> users = new ArrayList<>();
                            for (QueryDocumentSnapshot document : value) {
                                users.add(document.toObject(User.class));
                                Log.d(TAG, "User: " + users.get(i).toString());
                                i++;
                            }
                            firestoreCallback.onCallback(users);
                            Log.d(TAG, "Document updated.");
                        }
                        else {
                            Log.d(TAG, "No such document");
                        }
                    }
                });
    }
}

Далее:

 public class FirebaseGetUsers {

    //firebase objects
    private FirebaseAuth mAuth;
    private FirebaseFirestore mDbase;

    private Activity activity;

    private String adminID;

    //default constructor
    public FirebaseGetUsers() {
    }

    public FirebaseGetUsers(Activity activity) {
        this.activity = activity;

        //firebase new instances
        mAuth = FirebaseAuth.getInstance();
        mDbase = FirebaseFirestore.getInstance();

        if (mAuth.getCurrentUser() != null) {
            adminID = mAuth.getUid();
        }
    }

    public interface FirestoreCallback {
        void onCallback(List<User> users);
    }

    public void readDataRTUpdate(final FirestoreCallback firestoreCallback) {
        mDbase.collection("admins").document(adminID).collection("users")
                .addSnapshotListener(activity, new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot value,
                                        @Nullable FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.w(TAG, "Listen failed.", e);
                            return;
                        }
                        if (value != null) {
                            int i = 0;
                            List<User> users = new ArrayList<>();
                            for (QueryDocumentSnapshot document : value) {
                                users.add(document.toObject(User.class));
                                Log.d(TAG, "User: " + users.get(i).toString());
                                i++;
                            }
                            firestoreCallback.onCallback(users);
                            Log.d(TAG, "Document updated.");
                        }
                        else {
                            Log.d(TAG, "No such document");
                        }
                    }
                });
    }
}

Далее:

   public class FirebaseGetBooks {

    //firebase objects
    private FirebaseFirestore mDbase;

    private Activity activity;

    private String groupID;

    //default constructor
    public FirebaseGetBooks() {
    }

    public FirebaseGetBooks(Activity activity) {
        this.activity = activity;

        //firebase new instances
        mDbase = FirebaseFirestore.getInstance();

        FirebaseGetGroupID firebaseGetGroupID = new FirebaseGetGroupID(activity);
        groupID = firebaseGetGroupID.getGroupID();
    }


    public interface FirestoreCallback {
        void onCallback(List<Book> books);
    }


    public void readDataRTUpdate(final FirestoreCallback firestoreCallback) {
        mDbase.collection("books").whereEqualTo("groupID", groupID)
                .addSnapshotListener(activity, new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot value,
                                        @Nullable FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.w(TAG, "Listen failed.", e);
                            return;
                        }
                        if (value != null) {
                            int i = 0;
                            List<Book> books = new ArrayList<>();
                            for (QueryDocumentSnapshot document : value) {
                                books.add(document.toObject(Book.class));
                                Log.d(TAG, "Book: " + books.get(i).toString());
                                i++;
                            }
                            firestoreCallback.onCallback(books);
                            Log.d(TAG, "Document updated.");
                        }
                        else {
                            Log.d(TAG, "No such document");
                        }
                    }
                });
    }
} 

И, наконец, мой звонок в MainActivity:

    firebaseGetUsers.readDataRTUpdate(new FirebaseGetUsers.FirestoreCallback() {
            @Override
            public void onCallback(final List<User> users) {
                firebaseGetBooks.readDataRTUpdate(new FirebaseGetBooks.FirestoreCallback() {
                    @Override
                    public void onCallback(final List<Book> books) {
                        firebaseGetThisAdmin.readDataRTUpdate(new FirebaseGetThisAdmin.FirestoreCallback() {
                            @Override
                            public void onCallback(Admin admin) {
                                //processing all code here.
                                //books are empty!!
                                System.out.println("books: " + books.toString());
                                }
                            }
                        });
                    }
                });
            }
        }); 

Я не могу понять, что я делаю неправильно.... любые идеи будут с благодарностью.

Спасибо!

1 Ответ

0 голосов
/ 18 мая 2018

Хорошо, так что я смог наконец решить эту проблему.Это не имело никакого отношения к вложенным обратным вызовам Firestore.Если вы заметили в классе getBooks, я ссылаюсь на значение groupID.Это значение представляет учетную запись администратора (содержит ссылку как на пользователей, так и на других администраторов).Поскольку это значение никогда не меняется в течение всей жизни учетной записи, я храню его локально в общих настройках, чтобы уменьшить количество команд базы данных get ().Однако, похоже, что при первом входе в систему переменная groupID не устанавливается достаточно быстро, прежде чем мы попытаемся использовать ее для доступа к книгам из базы данных.

Итак, в результате книги не могутчтобы найти какие-либо документы, поскольку переменная еще не установлена.

Мое исправление для этого состоит из двух частей.Когда администратор создает свою учетную запись, groupID создается, когда мы создаем нашу первую ссылку на документ.На данный момент мы сохраняем его немедленно в sharedPrefs.На этом этапе не нужно пытаться получить его из базы данных, поскольку он создан и доступен локально.Во-вторых, я вложил обратный вызов getID () Firestore внутри нашего метода входа в Firestore.Поэтому все, что выполняется при входе пользователя в систему, происходит ПОСЛЕ того, как мы получаем это значение (для правильной очистки идентификатор группы очищается из sharedPrefs при каждом выходе из системы).

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