Query limited data in firebase - ios

I am working on an application that retrieves the posts from firebase. The problem is I want to retrieve the first 20 posts and show in a table. When a user clicks the next button, it will retrieve the next 20 posts and show and so on.
I know firebase provides the following methods
queryLimitedToFirst
queryLimitedToLast
queryStartingAtValue
queryEndingAtValue
queryEqualToValue
But how do I use them in conjunction to retrieve the desired results like I want?
Here is the structure of the data I have:

You should order query by some property (I usually use timestamp). This organises your orders from latest to oldest. When you have them ordered you should limit them:
queryOrdered(byChild: "timestamp").queryLimited(toLast: UInt(limit))
As you can see we can limit results to whatever number we like. You can use this to read your posts each time for 20 results more.
So the first time you call it with a limit of 20, next time with a limit of 40, etc. Keep in mind that this will return posts that were already returned in the previous call.
Instead you could combine it with queryStartingAtValue and use your last post tiemstamp - this will "skip" your previous results and return only 20 posts you need.
This is just an idea but I think it should work like expected.

Related

Firebase database structure and query format options

Basically, my app has posts based on location that can be upvoted/downvoted.
I need to construct a query that returns the top 15 upvoted posts that lie in a specified region, and were made in the last 24 hours. Coming from an sql background, I am finding this unnecessarily difficult to do with the JSON format and firebase's built in query by order and filtering options. I realize i will most likely have to a lot of client side filtering, so I am asking what the JSON structure and query format would be to minimize client side filtering. So far this is what my JSON format looks like:
"posts" : {
"-KPFIsDbf3WUljWvBwi-" : {
"latitude" : 33.64114800203589,
"longitude" : -116.4236003651668,
"time" : 1.47129994542173E12,
"uid" : "wjXpBBJMBVPvRVG48fFkerAw6TD3",
"upvotes" : 0
},
I tried using Geofire, but unfortunately that seems to only have the ability to query by region, and since I want to query by region and time posted (among other things), using Geofire will not scale well.
Here's what I would do in a similar setup, using a combination of GeoFire and Firebase queries:
Step 1 (saving): When saving a post, save it to the database first, using a random ID. Then, grab that ID, create a GeoFire location, and set your post ID as the location key.
Step 2 (querying): This will be a 2 step query
Step 2a: Get all GeoFire locations within specified region. Now, you can grab the keys of all locations from the snapshots and and attach a single data event handler on each.
Step 2b: Maintain a sorted array of post objects by number of upvotes. In the snapshot for single event listener, first check the timestamp to see if it is within the last 24 hours. Next, if the array has a count of less than 15, add your post in sorted position (using an appropriate parsing method). If it already has 15, you'll need to see if the minimum lowest element in the array has more upvotes. If it does not, you'll need to find a place in the array to replace. After you are done parsing through every snapshot from Geofire, you will have your array of posts from the last 24 hours, sorted by upvotes.

How to implement infinite scroll with multiple filter on data that get from Firebase in Swift?

I'm using Firebase for my iOS application and I'm having trouble implement infinite scroll and filtering data together.
What I need to do is:
Display items with order/filter on multiple property (location, category, status . . .)
Implement infinite scroll when the user scrolled to bottom of the screen.
I tried to think about some solutions:
The first, I think that I'll query the data with the necessary conditions then limit the number of records by use queryLimitedToFirst(N), and increase N when need to load the next items. But because Firebase can only filter on one property at a time and it's also a waste to reload data. So, I was thinking about the second solution.
As approaches are suggested from Frank van Puffelen (Query based on multiple where clauses in firebase):
filter most on the server, do the rest on the client
Yes, exactly like that. I'll execute queryOrderedByKey, queryStartingAtValue, queryEndingAtValue to implement infinite scroll, pull down the remaining data and filter that on client. But there is one problem that is I would not have enough items to display for the user if execute filter on the client.
For example: each time run the query, I receive 10 items. After data filtering process on the client, I just left 5 (can be 0) items meet the conditions to display to the user.
I don't want this because user may think there is a problem
Can I please get some pointers on this? If I didn't structured the data properly, can I also get some tips there?

query firebase database by ordering two values in iOS swift

I have a database of posts in firebase, and each has a timestamp and a rating.
i know how to order by time OR by rating, but would it be possible to order by rating, then limit by time. ie. show highest rated posts over the last week?
ie.
Ref.queryOrderedByChild("rating").observeSingleEventOfType(.Value, withBlock: {...}
would order by rating, but how would i then limit the query by time, and not rating?
Unfortunately, Firebase does not support cross referencing nor server-side logic, so you'll probably have to query by the more specific value, pull the data down, then sort the rest client side.
Alternatively, you could also try to get creative with GeoFire (firebase's cross referencing solution for latitude/longitude location querying), though that'll the hackiest solution ever...

minimizing parse requests while looping through array

I'm working on a pet project using parse as a back end. I'm setting up a viewcontroller that contains a list of people you can possibly add as "friends"; these are people that
a) exist in your contacts list and
b) have already downloaded the app and signed up.
Different buttons will be displayed depending on their status as a user (invite button if they only exist in your contacts list, add to friends button if they're also using the app already).
I'm trying to keep my Parse account to 30 requests/second so that I'm not out of pocket for a pet app.
One way I've thought to figure out who is registered as a user AND who exists in my contacts list is to loop through the contacts list on my phone and query that phone number on parse. However, this would obviously go over my limit on requests/second.
Is there a way (I've looked through Parse documentation and googled it) to take an array (list of contacts on my phone) and run a PFQuery ON THAT ARRAY, checking each object and returning matches?
Unless you have a quarter million users in your app you shouldn't be much concerned, it doesn't work like: 1 user goes through 30 count for loop with one query each and you get 30 req/s:
How does the requests/second limit translate to concurrent users?
Generally when your user count doubles, your requests per second also double. However, different apps send different numbers of requests per second depending on how frequently they save objects or issue queries. We estimate that the average app's active user will issue 10 requests. Thus, if you had a million users on a particular day, and their traffic was evenly spread throughout the day, you could estimate your app would need about 10,000,000 total API requests, or about 120 requests per second. Every app is different, so we strongly encourage you to measure how many requests your users send.
I have run through loops of requests and I barely hit 1 req/s
Is there a way (I've looked through Parse documentation and googled
it) to take an array (list of contacts on my phone) and run a PFQuery
ON THAT ARRAY, checking each object and returning matches?
Yes there is, use:
query?.whereKey(key: String, containedIn: [AnyObject])

How to build rails analytics dashboard

I'm looking to build an analytics dashboard for my data in a rails application.
Let's say I have a list of request types "Fizz", "Buzz", "Bang", "Bar".
I want to display a count for each day based on type.
How should I do this?
Here is what I plan on doing:
Add get_bazz_by_day, get_fizz_by_day, etc to the appropriate models.
In each model get all records of type Fizz, then create an array that stores date and count.
format in view so a JS library can format it into a pretty graph.
Does this sound reasonable?
Depending on number of records, your dashboard can soon get performance problems.
Step 1 is misleading. Don't get the data for each day individually, try to get them all at once.
In Step 2 you can have the database do the the aggregation over days, with the group method.
See http://guides.rubyonrails.org/active_record_querying.html#group
Fizz.select("date(created_at) as fizzed_day, count(*) as day_count").
group("date(created_at)")
In Step 3 you need to take care that days without any fizzbuzz are still displayed, as they are not returned in the query.

Resources