How to retrieve range of data in firebase - firebase

I have user's data which have uuid as their key. I want to send mail to each user, But I don't want to send them mail all together so I want to retrieve range of user.
For example, I have 1000 user's now I want to send mail to range 1-100 user then 101-200 , 201-300 and so on. How can I achieve this?
I have seen startAt() and endAt() functions, but my question is I don't know user key at the beginning and at the end. So I won't be able to retrieve range from that way.

To get the first 100 users you'd do a query on:
query = ref.orderByKey().limitToFirst(100)
Then as you process the users, keep track of the last key you've processed:
vast lastSeenKey;
query.once("value", function(snapshot) {
snapshot.forEach(function(userSnapshot) {
lastSeenKey = userSnapshot.key;
});
});
And then to load the next 100 users, you make the query start at the last key you've seen:
query = ref.orderByKey().startAt(lastSeenKey).limitToFirst(101)
You'll note that we retrieve one extra item here, since the first user in this query will be the same as the last user in the previous query.

Related

Firebase - Generate a user see-able unique account/document number

I want to assign a unique but incremental document/record(a data entry, not Firebase document) number when user generates his/her document in the app.
The document number should be unique integer/long and will be visible on the generated PDF document of the user as Your document number : 1100xxxxxx. This last generate document's number will be stored separately so when a new user generated his/her document, this number can be easily picked, incremented and assigned to user.
This way I won't have to query the database again for the last generated number using sorting as
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.collection("Users")
.orderBy("DocumentNo", Query.Direction.DESCENDING)
.limit(1);
Right now, I generate a user by assigning the user.uid to the Firebase document. The reason I want to ensure the uniqueness of generated certificate number is that it will be visible to user and multiple users will be hitting the server at the same time(same millisecond even).
Although, I've seen almost every similar answer but the answer I've found similar to what I was thinking is this. Also, this unanswered question is what I should do but it has problems too.
So, is there a way by which I can generate a unique document/record number to the user? Answer need not be in Flutter, I want the logic mainly.
If you want to increment a number every time something happens do:
document.ref.update({unique_value: FieldValue.increment(1)});
That number will be unique. It will work with multiple users hitting the server at the same time.

Firebase Cloud Firestore request

I have a MESSAGERECAP collection which includes a unique id for each message, the id of the receiver of the message, the id of the sender and the message itself. In my application, when the user clicks on a friend to chat with him, I want the chat activity to start with the list of messages they have both sent.
I did this but obviously it does not give the desired result :
Query query = messageRef.orderBy("mssgId",Query.Direction.DESCENDING);
// with messageRef a reference to the MESSAGERECAP collection
Here is an overview of my database
You are getting the whole list because you are not filtering the data, just ordering it. If you check the Querying documentation for Firestore, also provided by #FrankVanPuffelen on the comments of your question, you can see that you have to use .where() to filter the data that you want to retrieve.
Also, as pointed out by #Jay in the comments, you can use Compound Queries to create a logical AND on your query to retrieve the data you want.
So if you do something like:
messageRef.where("senderId", "==", [currentUserId])
.where("receiver_id", "==", [receiverUserId])
.orderBy("mssgId",Query.Direction.DESCENDING)
When you execute this query you will get all the messages sent by the current user to the receiving user of the correponding id.

NoSQL query of items,lists, Groups and Users using Firebase

Am looking at the data structure in this post and want to know how you would go about getting the emails of users who belong to a certain group when they could belong to several groups and the GroupID stored against that user is the current group they are participating in?
Do you store the email addresses with the userid under the "members" or, instead, for each member of the group, get that user's email address from the "users" document userid (this would mean iterating through the group/members collection and doing a query for each user. Not very efficient).
Am used to SQL so this is all new to me.
You should have a single node for each user
/users/UID/emails/
/users/UID/emailunread/
/users/UID/settings/
/users/UID/details/
/users/UID/payments/
So you can simply do a subscription for a singular node path this.myDatasubscription = this.DB.list('users/' + this.uid).snapshotChanges() ensuring changes like new emails or account settings will detected and rolled out in real time back to the app, so your are using angular/ng or something similar client side then your variables {{this.email_list}} should update real time with no page changes.
Take a look at this one.
error: Property 'getChildren' does not exist on type 'DataSnapshot'

Efficiently storing and retrieving likes

In my Firebase database I have posts and then authenticated users can "like" posts. How can I efficiently get the number of likes a post has received. I know using MongoDB I can add/remove the user's id to a list and then use a MongoDB function to get the length of it very quickly and set that equal to the likes amount, but I'm not suer how to do that using Firebase. I could also add/remove it to the list and increment a likeCount variable, but that seems like it would cause concurrency issues unless Firebase has a function for that. What functions can I call to best handle this and scale well? Thanks in advance!
You can do both things:
1) Create a votes node with the UID as key and a value to sum up all the votes.
post:{
//All the data
likes:{
$user_1:1,
$user_2:-1,
}
}
And then just get a SingleValue Event or a Value event(depending if you want to keep track of changes) and sum up all the children
2)You can use a transaction block and just save a value and increase or decrease it depending on the votes
(here is a link where you can find transactions for android,iOS or java)
https://firebase.google.com/docs/database/web/save-data#save_data_as_transactions
post:{
//All the data,
likes:2,
}
It really depends on how much information you want to store, and what the user can do once he/she already voted for some post,
I would recommend using both, to keep flexibility for the user to like (like in Facebook) so he can unlike something and use the transaction with number to keep it scalable.. so if a post gets 1,000,000 likes you don't have to count the 1,000,000 likes every time someone loads the post

handle multiple arrays in event result

I am writing an mobile app that retrives some data from an amf webservice and stores it in a database table(s). I don't always know what I will get returned as I send it a customer id and it returns all the information that the system has for that customer. Each set of information is returned as an array.
So I end up with a event.result that contains
user
orders
sales
profile
each one of those items can have multiple items under them, if the customer does not have any orders that that is not returned and I would have
user
sales
profile
so what I need to do is determine which arrays are returned and then insert/update them in the database. I have tried the following
var sales:Array
if (event.result.sales)
{
sales = event.result.sales
}
watching through the debugger it enters the if statement but once is completes sales is still null.
so I guess my question is what am I doing wrong? or is there a much better way of handling this
Thanks

Resources