Reputation: 14837
I read the Firebase blog for using architecture components.
Source: https://firebase.googleblog.com/2017/12/using-android-architecture-components.html
Now to implement the same in my app, I would like to know how to convert the Firebase Document Reference
to Firebase Query
datatype.
Can someone help me with it?
I assume the code is not really necessary, but still providing it for better clarification.
Note:
1. I am using Firebase Firestore (the reference blog use firebase real-time database), and hence I have altered the code (referring another SO post).
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);
}
}
}
View model with Firebase collection reference (which is of Query datatype according to firebase docs.)
// 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;
}
Code with Document Reference:
private static final DocumentReference documentReference = FirebaseFirestore.getInstance()
.collection("cart")
.document(Objects.requireNonNull(firebaseUser).getUid());
private static final Query QUERY = documentReference;
In the above code snippet :
private static final Query QUERY = documentReference;
line shows the following error:
Incompatible types.
Required: com.google.firebase.firestore.Query
Found: com.google.firebase.firestore.DocumentReference
Screenshot of the database:
The document Id is used to fetch a document and hence I end up with Document reference and not Collection reference.
Upvotes: 1
Views: 2435
Reputation: 14837
This is not an exact answer but a doable hack, I used in my app.
Created another file for handling Document reference and used files according to the requirement.
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);
}
}
}
Upvotes: 1
Reputation: 138969
You are getting the following error:
Incompatible types. Required: com.google.firebase.firestore.Query Found: com.google.firebase.firestore.DocumentReference
At this particular line of code:
private static final Query QUERY = documentReference;
Because your are trying to assign a DocumentReference object to a Query object.
How to convert Firebase Document Reference to Firebase Query?
This is actually not possible in Java since between these two classes there is no inheritance relationship. You could assign a CollectionReference because it extends Query class but never a DocumentReference
.
To get a single document, simply use DocumentReference
object and never assign it another type of object.
Upvotes: 2