#android #firebase #google-cloud-firestore
#Android #firebase #google-облако-firestore
Вопрос:
Я прочитал блог Firebase об использовании компонентов архитектуры.
Source: 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 (которая относится к типу данных запроса в соответствии с документами 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.
Найден запрос: com.google.firebase.firestore.DocumentReference
Скриншот базы данных:
Идентификатор документа используется для извлечения документа, и, следовательно, я получаю ссылку на документ, а не ссылку на коллекцию.
Комментарии:
1. Пожалуйста, добавьте скриншот структуры вашей базы данных.
2. @AlexMamo добавили скриншоты
3. Возможно, вам следует просто скопировать то, что здесь вместо этого: github.com/CodingDoug/firebase-jetpack
4. @DougStevenson Я все еще не силен в kotlin. Есть ли какой-либо Java-код, на который я могу сослаться.
5. Просто поймите, что он пытается сделать, и напишите эквивалентную Java. Это не должно быть так сложно. Все шаблоны есть.
Ответ №1:
Вы получаете следующую ошибку:
Несовместимые типы. Требуется: com.google.firebase.firestore.Найден запрос: com.google.firebase.firestore.DocumentReference
В этой конкретной строке кода:
private static final Query QUERY = documentReference;
Потому что вы пытаетесь присвоить объект DocumentReference объекту запроса.
Как преобразовать ссылку на документ Firebase в запрос Firebase?
На самом деле это невозможно в Java, поскольку между этими двумя классами нет отношения наследования. Вы могли бы назначить CollectionReference , потому что он расширяет класс запроса, но никогда a DocumentReference
.
Чтобы получить один документ, просто используйте DocumentReference
object и никогда не назначайте ему объект другого типа.
Комментарии:
1. Спасибо за ответ, я хорошо осведомлен о несоответствии типов данных. Я могу использовать ссылку на документ для выполнения необходимого запроса, но я пытаюсь реализовать компонент архитектуры так, как показано в блоге, о котором я упоминал.
2. Я понимаю это, но в этом случае вы должны шаг за шагом реализовать решение, предоставленное Дугом Стивенсоном в этом блоге. Я не думаю, что где-нибудь в этом блоге есть такое назначение. Таким образом, ошибка появляется только из-за этого неправильного назначения.
Ответ №2:
Это не точный ответ, а выполнимый хак, который я использовал в своем приложении.
Создал другой файл для обработки ссылки на документ и использовал файлы в соответствии с требованиями.
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);
}
}
}