Get db from current user firestore query kotlin android - android

whats up?
I have an app that displays a list of items on Firestore using Kotlin and RecyclerView (from FirebaseUI api).
The DB is structured like this:
Users/userID/document_month_year
I need to query the data from the current user.
Each user has his own document_month_year document.
I read a lot of posts here, but each one tell one thing.. thereĀ“s no consense and nothing seems to work.
This query just sends me all documents from all users, how can I fix this?
private val queryFilteredByPaidStatus = db.collectionGroup(collectionName).whereEqualTo("users", userId)

Like this is an important question, here is the awnser that I
private val queryTest = db.document("users/"+userId).collection(collectionName)
fun getData() : FirestoreRecyclerOptions<Expense> {
return FirestoreRecyclerOptions
.Builder<Expense>()
.setQuery(queryTest, Expense::class.java)
.build()
}

Create a separate collection for documents to be read i.e month_year and for each document, add a field inside it which tells you the uid of the authenticated user, to which the document belongs to. Now you can query the collection like:
firestoreDB.collections("month_year").whereEqualTo("uid",auth.currentUser.uid)

Related

Display images from Firebase Storage order by date added in Android

I am trying to display images from Firebase's storage in my Android app inside a GridView.
I have done that, however, the images are displaying in an unknown order, and I have noticed that there is a 'Last modified' column inside Firebase's storage when I upload the images to it.
My question is: is there a way that I could sort the images inside the GridView in order to display them according to that date? (for example, the last one added, would have the latest 'Last modified' date and would be viewed first and such...)
This is my code:
val listRef : StorageReference = FirebaseStorage.getInstance().reference.child("images/posts/$userName")
val fileNameList: ArrayList<String> = ArrayList<String>()
listRef.listAll()
.addOnSuccessListener { it ->
it.items.forEach{
fileNameList.add(it.name)
}
gridView?.adapter = ImageRecyclerAdapter(activity, fileNameList,userName)
}
Note: the code is in Kotlin
I have looked everywhere and couldn't find anything that helps.
Any help is appreciated, thank you :)
According to the official documentation regarding StorageReference's listAll() method:
List all items (files) and prefixes (folders) under this StorageReference.
You might not be interested in listing folders within the reference you are pointing to.
That been said, the best option that you have is to store the URLs in a database. Such a database can be either Cloud Firestore or Firebase Realtime Database. This means that each object should have at least two fields, one for the actual URL and one for a timestamp. Please see in my answer from the following post how you can add a timestamp to Firestore:
ServerTimestamp is always null on Firebase Firestore
Is in Java, but you can simply convert it to Kotlin. Once you have all URLs in place, you can create a query and order the URLs according to the date. In Firebase Realtime Database the default order is ASCENDING, but below is how you can reverse the order:
How to arrange firebase database data in ascending or descending order?
While in Firestore, you can simply pass the desired direction to Query's orderBy(String field, Query.Direction direction) method.

Android's Firestore to join 2 collections into a recycler view

I have a users collection with uId, name, photo
I have a visits collection with uId, userId, location
I have a recyclerview in which I want to show the location with the user name and photo
Can I use the reference field type? If so, how will Firestore know to link visits.userId == users.uId ?
Maybe I first need to query all the visits and then query the relevant user but 2 things:
It means querying a lot of times.
I didn't understand how to collect the joined collection into the adapter, which is based on one query?
Please advice
Thanks
current code
visitsList = db.collection("visitsList");
Query query = visitsList.whereEqualTo("userId",prefs.getString("id","")).orderBy("visitDate", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<AVisit> options = new FirestoreRecyclerOptions.Builder<AVisit>().setQuery(query, AVisit.class).build();
adapter = new VisitsListAdapter(options, VisitsListActivity.this);
RecyclerView rv = findViewById(R.id.rvVisitsList);
rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(adapter);
The code is a simple query from the collection, not sure how to get the name and photo from the userId field in that collection.
Can I use the reference field type?
Yes, you can use a reference field.
If so, how will Firestore know to link visits.userId == users.uId ?
Firestore results always comes from a single collection (at the moment). It does not automatically join the document from the users collection when you're reading from the visits collection. You will have to do this yourself.
That indeed means you'll be executing multiple reads, but it's often not nearly as slow as you may think. See Google Firestore - how to get document by multiple ids in one round trip?
Update: To show data from the user profile in a list of visits, there are two main options:
load the additional user document in populateView or with a custom parseSnapshot implementation.
duplicate the relevant user data in the visits collection (which is quite normal in NoSQL databases). Also see Alex' answer here: indexed query with FirestoreRecyclerAdapter.

How to get just one child from FIrebase Realtime Database instead of whole list

I am implementing Firebase Realtime Database for my app.
The database contains a lot of entries that will continue to grow in the future.
I want to retrieve only a specific child from the database, but i can't find any implementation for doing that.
In Firebase too the implementation retrieves all the entries from the database.
This will be cumbersome in the future.
Is there any way to retrieve only specific entries or just one entry(depending upon the customisation)?
Please help.
#ALex Mamo: This is the database image
Perhaps you are refering to shallow query, which only read the first child ? In this case you might want to look at the API implementation as mentioned here:
Firebase (2016) Shallow Query
There are two different ways of getting it. You'll have to change 'messages' to the name of your database. Replace PostTitle with the specific data you're trying to receive.
var rootRef = firebase.database().ref().child("messages");
rootRef.on("child_added", snap=> {
var postTitle = snap.child("PostTitle").val();
or
exports.sendPushNotification = functions.database.ref('/messages/{id}').onWrite((change, context) => {
const afterData = change.after.val();
const postTitle = afterData.PostTitle;
if you want retrieve few records this might help. as per image structure attached.
you can restructure the data, and use set method with keys as 0,1,2.... instead of "LK34h...."->0 .
use set method and store latest index value.
you retrive like this
firebase.database().ref().child('users_Post/0').on('value',sn=>{ console.log(sn.val())//use sn.val() })

How to get value of some field in firebase firestore android?

Like upper question, i want to get value of some field in firebase firestore instead of all document with DocumentSnapshot
like this in SQL SELECT col_1, col_2, col_3 FROM table_name
How can i do it?
Thank you for the help.
The Cloud Firestore client-side SDKs always read and returns full documents. There is no way to read a subset of the fields in a document.
You can retrieve the entire document, and then process the DocumentSnapshot to just use the fields you're interested. But this means you're using more bandwidth than needed. If this is a regular occurrence for your app, consider creating a secondary collection where each document contains just the fields you're interested in.
Also see Doug's answer here (for Swift): How to access a specific field from Cloud FireStore Firebase in Swift
Firestore can read single field value.
Firebase guides looks like didn't show these simple method.
For example:
[android]
String value = document.getString("col_1");
[node.js]
const value = doc.data().col_1
Firebase allows a few ways to query like an RDBMS database. And these are very handy too. Try the Where clause. It returns a single document but u can add multiple filters.
check for more
try this code:
//set a global variable
dataList: Array<any>;
const dataCollection = firebase.firestore().collection('data');
dataCollection.get(query => {
query.forEach(docs => {
this.dataList.push({id: doc.id, data:doc.data()});
})
})

How to iterate through greendao list?

Please help, i'm kinda newbie when it comes to android app with a database.
In Greendao documentation there's a point of having this code:
List users = usersDao.queryBuilder().orderDesc(Properties.Id).list();
But somehow, it is not documented well on how to exactly get the values of rows from that query builder? or is there even a point where I could only get the first row, or last row from the database?
Thanks in advance for someone who will help.
Entity class are similar to all other classes. So greendao generates properties for all rows and you can access them as you access all others properties form "normal" classes.
To access Id property of UserEntity you can use getter user.getId().
From this query you are getting list of users. You can access it as you are accessing any other list in Java.
To get first user from database you can use code similar to:
List<User> users = usersDao.queryBuilder().orderDesc(...).limit(1).list();
if (users.size() < 1) return null;
return users.get(0);
To get last user I suggest to use similar query with reversed order:
List<User> users = usersDao.queryBuilder().orderAsc(...).limit(1).list();
if (users.size() < 1) return null;
return users.get(0);
If your query returns only one unique entity you can use unique method:
User user = usersDao.queryBuilder().where(...).unique();
You don't need to build these queries all the time. You can build it once, and then reuse it:
private Query<User> mSomeUserQuery;
...
// initialization
mSomeUserQuery = usersDao.queryBuilder().where(...).build();
// usage
User user = mSomeUserQuery.forCurrentThread().unique();
Greendao lists are not different to other lists in Java. You just have to google how to iterate through lists. Result: Ways to iterate over a List in java?
But here is the answer with the example to get the name value from an user:
for(User user : users){
String name = user.getName();
}

Categories

Resources