Как преобразовать ссылку на документ Firebase в Firebase Query? - PullRequest
0 голосов
/ 09 апреля 2019

Я прочитал блог Firebase по использованию компонентов архитектуры.
Источник: https://firebase.googleblog.com/2017/12/using-android-architecture-components.html

Теперь, чтобы реализовать то же самое в моем приложении, я хотел бы знать, как преобразовать тип данных Firebase Document Reference в Firebase Query.

Может ли кто-нибудь помочь мне с этим?

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

Примечание:
1. Я использую Firebase Firestore (справочный блог использует базу данных Firebase в реальном времени), и, следовательно, я изменил код (ссылаясь на другой пост SO).

FirebaseQueryLiveData.java:

public class FirebaseQueryLiveData extends LiveData<QuerySnapshot> {

//  Logging constant
private static final String TAG = "FirebaseQueryLiveData";

//  Query
private final Query query;

//  Listener
private final MyValueEventListener listener = new MyValueEventListener();
private ListenerRegistration listenerRegistration;

//  Handler
private final Handler handler = new Handler();

//  Flag to remove listener
private boolean listenerRemovePending = false;

//  Remove listener runnable
private final Runnable removeListener = new Runnable() {

    @Override
    public void run() {
        listenerRegistration.remove();
        listenerRemovePending = false;
    }
};

public FirebaseQueryLiveData(Query query) {
    this.query = query;
}

@Override
protected void onActive() {
    super.onActive();
    Log.d(TAG, "onActive");

    //  Check flag
    if (listenerRemovePending) {
        handler.removeCallbacks(removeListener);
    } else {
        listenerRegistration = query.addSnapshotListener(listener);
    }

    //  Update flag
    listenerRemovePending = false;
}

@Override
protected void onInactive() {
    super.onInactive();
    Log.d(TAG, "onInactive");

    // Listener removal is schedule on a two second delay
    handler.postDelayed(removeListener, 2000);

    //  Update flag
    listenerRemovePending = true;
}

//  Listener definition
private class MyValueEventListener implements EventListener<QuerySnapshot> {

    @Override
    public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
        Log.d(TAG, "onEvent");

        //  Check for error
        if (e != null) {
            Log.d(TAG, "Can't listen to query snapshots: " + queryDocumentSnapshots
                    + ":::" + e.getMessage());
            return;
        }

        //  Set value if listening is successful
        setValue(queryDocumentSnapshots);
    }
}
}

Просмотр модели со ссылкой на коллекцию Firebase (которая имеет тип данных Query согласно документации Firebase.)

//  Initialize Firebase variables
private static final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
private static final FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();

//  Query
private static final Query QUERY = FirebaseFirestore.getInstance().collection(COLLECTION_ORDERS)
        .whereEqualTo(ATTRIBUTE_USER_UID, Objects.requireNonNull(firebaseUser).getUid());

//  Firebase query live data
private final FirebaseQueryLiveData firebaseQueryLiveData =
        new FirebaseQueryLiveData(QUERY);

@NonNull
public LiveData<QuerySnapshot> getQuerySnapshotLiveData() {
    Log.d(TAG, "getQuerySnapshotLiveData");
    return firebaseQueryLiveData;
}

Код со ссылкой на документ:

private static final DocumentReference documentReference = FirebaseFirestore.getInstance()
        .collection("cart")
        .document(Objects.requireNonNull(firebaseUser).getUid());

private static final Query QUERY = documentReference;

В приведенном фрагменте кода:
private static final Query QUERY = documentReference;
строка показывает следующую ошибку:

Несовместимые типы.
Требуется: com.google.firebase.firestore.Query
Найдено: com.google.firebase.firestore.DocumentReference

Скриншот базы данных:

enter image description here

Идентификатор документа используется для извлечения документа, поэтому я получаю ссылку на документ, а не на коллекцию.

Ответы [ 2 ]

0 голосов
/ 02 мая 2019

Это не точный ответ, а выполнимый хак, который я использовал в своем приложении.

Создан другой файл для обработки ссылки на документ и используемых файлов в соответствии с требованием.

FirebaseDocumentLiveData.java

public class FirebaseDocumentLiveData extends LiveData<DocumentSnapshot> {


    // Logging constant
    private static final String TAG = "FirebaseQueryLiveData";

    // Document Reference
    private final DocumentReference documentReference;

    // Listener
    private final MyDocumentListener listener = new MyDocumentListener();
    // Handler
    private final Handler handler = new Handler();
    private ListenerRegistration listenerRegistration;
    // Flag to remove listener
    private boolean listenerRemovePending = false;

    // Remove listener runnable
    private final Runnable removeListener = new Runnable() {

        @Override
        public void run() {
            listenerRegistration.remove();
            listenerRemovePending = false;
        }
    };


    // Constructor
    public FirebaseDocumentLiveData(DocumentReference documentReference) {
        this.documentReference = documentReference;
    }


    // On active
    @Override
    protected void onActive() {
        super.onActive();
        Log.d(TAG, "onActive");

        // Check flag
        if (listenerRemovePending) {

            // Remove callbacks
            handler.removeCallbacks(removeListener);
        } else {

            // Add listener
            listenerRegistration = documentReference.addSnapshotListener(listener);
        }

        // Update flag
        listenerRemovePending = false;
    }

    // On inactive
    @Override
    protected void onInactive() {
        super.onInactive();
        Log.d(TAG, "onInactive");

        // Listener removal is schedule on a two second delay
        handler.postDelayed(removeListener, 2000);

        // Update flag
        listenerRemovePending = true;
    }

    // Listener definition
    private class MyDocumentListener implements EventListener<DocumentSnapshot> {

        @Override
        public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
            Log.d(TAG, "onEvent");

            // Check for error
            if (e != null) {

                // Log
                Log.d(TAG, "Can't listen to query snapshots: " + documentSnapshot
                        + ":::" + e.getMessage());
                return;
            }

            // Set value if listening is successful
            setValue(documentSnapshot);
        }
    }
}
0 голосов
/ 09 апреля 2019

Вы получаете следующую ошибку:

Несовместимые типы.Обязательно: com.google.firebase.firestore.Query Найдено: com.google.firebase.firestore.DocumentReference

В этой конкретной строке кода:

private static final Query QUERY = documentReference;

Поскольку выпытается присвоить объект DocumentReference объекту Query .

Как преобразовать ссылку на документ Firebase в запрос Firebase?

На самом деле это невозможно в Java, поскольку между этими двумя классами нет отношений наследования.Вы можете назначить CollectionReference , поскольку он расширяет класс Query, но никогда не DocumentReference.

Чтобы получить отдельный документ, просто используйте объект DocumentReference и никогда не назначайте ему другой тип объекта.

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