I am trying to build a next.js server-side rendered blog. For it, I need to paginate the posts data. However, I am yet to find a way to use the query cursors firebase provides to paginate the data. The building query code is:
let postsQuery = firebase.firestore().collection('/posts').orderBy('postedOn', 'asc').limitToLast(10);
if (currentTagFilter !== 'All') {
postsQuery = postsQuery.where('tag', '==', currentTagFilter);
}
Now, this works for the first page, but I do not know how to request the next 10 posts. I could have saved the first document of the query and use .endBefore(firstPost). But, if I create some state in _app.js and save the first document in an array, for example, I cannot find how to make it accessible in getServerSideProps. Not to mention, if the user goes straight to /page/2, nothing will be displayed to him as the query for page 1 has not been performed yet.
How can I paginate the data correctly?
You might want to rethink you pagination strategy entirely. Firestore doesn't support pagination by index or page number. You have to provide a document snapshot or document details from the last seen document in order to get the next page.
Given these limitations and requirements, it's not possible for the user to go straight to page 2 (or any page other than the first one). So, it would be a bad idea to provide a link or mechanism to do that.
If you want to paginate data "correctly" with Firestore, you have to start at the first page, and cycle through the results using startAfter(), providing the details of the document where the last page ended. This is illustrated in the documentation.
Related
I would like to understand better Firebase Dynamic Links because i am very new to this subject.
What i would like to know :
FirebaseDynamicLinks.instance.getInitialLink() is supposed to return "only" the last dynamic link created with the "initial" url (before it was shorten) ?
Or why FirebaseDynamicLinks.instance.getInitialLink() doesn't take a String url as a parameter ?
FirebaseDynamicLinks.instance.getDynamicLink(String url) doesn't read custom parameters if the url was shorten, so how can we retrieve custom parameters from a shorten link ?
My use case is quite simple, i am trying to share an object through messages in my application, so i want to save the dynamic link in my database and be able to read it to run a query according to specific parameters.
FirebaseDynamicLinks.instance.getInitialLink() returns the link that opened the app and if the app was not opened by a dynamic link, then it will return null.
Future<PendingDynamicLinkData?> getInitialLink()
Attempts to retrieve the dynamic link which launched the app.
This method always returns a Future. That Future completes to null if
there is no pending dynamic link or any call to this method after the
the first attempt.
https://pub.dev/documentation/firebase_dynamic_links/latest/firebase_dynamic_links/FirebaseDynamicLinks/getInitialLink.html
FirebaseDynamicLinks.instance.getInitialLink() does not accept a string url as parameter because it is just meant to return the link that opened the app.
Looks like there's no straightforward answer to getting the query parameters back from a shortened link. Take a look at this discussion to see if any of the workarounds fit your use case.
I'm setting up a PrismTabbedPage dynamically in Xamarin.Forms. I have a content page PrismContentPageProfile which shows the profile of a given Id. The Id I want to pass with a parameter. Problem is that each initialize is having all the parameters.
await NavigationService.NavigateAsync("NavigationPage/PrismTabbedPage1?createTab=PrismContentPageProfile?Id=Michel&createTab=PrismContentPageProfile?Id=Erik");
I expect to tabs. One for the profileId Michel and one for Erik. Problem is that the paramters in the Initialize look like this on each page:
{?createTab=PrismContentPageProfile%3FId%3DMichel&createTab=PrismContentPageProfile%3FId%3DErik}
As I don't know which tab I am, I don't know which profile to load.
I hoped that calling:
await NavigationService.NavigateAsync("NavigationPage/PrismTabbedPage1?createTab=PrismContentPageProfile?Id=Michel&createTab=PrismContentPageProfile?Id=Erik");
would result in different parameters on each page. Id=Michel on the first page, Id=Erik on the second.
Or, if that is not possible, that I know which tab index I am. Then I can read the related parameter.
I currently have an application that works with Firebase.
I repeatedly load profile pictures. However the link is quite long, it consumes a certain amount of data. To reduce this load, I would like to put the link in raw and only load the token that is added to the link.
To explain, a link looks like this: “https://firebasestorage.googleapis.com/v0/b/fir-development.appspot.com/o/9pGveKDGphYVNTzRE5U3KTpSdpl2?alt=media&token=f408c3be-07d2-4ec2-bad7-acafedf59708”
So I would like to put in gross: https://firebasestorage.googleapis.com/v0/b/fir-developpement.appspot.com/o/
In continuation: “9pGveKDGphYVNTzRE5U3KTpSdpl2” which is the UID of the user that I recover already and the or my problem this poses: “alt = media & token = f408c3be-07d2-4ec2-bad7-acafedf59708” which adds randomly for each photo .
I would like to get back only this last random piece …
Is it possible ?
Thank you
UP : 01/11 Still no solution
It's not supported to break apart and reassemble download URLs. You should be treating these strings as if their implementation details might change without warning.
How can I make certain parameters of the WordPress Rest API accessible to anyone without first being authenticated – for example, the page parameter doesn't work (where blog is a custom post type) in this query:
mysite.com/wp-json/wp/v2/blog?page=2&per_page=20
I've seen that in the past it's been possible to make these params available, for instance :
add_filter( 'json_query_vars', function( $valid_vars ) {
$valid_vars[] = 'offset';
return $valid_vars;
});
Is there any way to do something similar with today's version of the API?
For anyone who has the same problem, I've solved it. The page parameter is actually publicly available, offset is the one you need authentication for.
The reason the API didn't paginate was because the request url didn't have the paged query string set. Every time I tried to add it with the params option of the WordPress Node API, it didn't work:
wpapi.getNews().params('paged', 'paged').perPage( perPage ).page( pageNumber ).then(data=>
It didn't work because the request url created by the API seemed to always put the page parameter before the paged one, which resulted in paged being ignored when the query actually runs.
So in the end, I created a custom query (bit of a hacked way to do it, but it worked) like so:
Register the route:
wpapi.getNews = wpapi.registerRoute('wp/v2', '/news/(?P<customQuery>)');
Usage:
wpapi.getNews().customQuery('?paged&per_page=20&page='+pageNumber).then(data =>
Using the above, you can build any query, in any order you want. This helped me get the correctly paginated result. Also, we see 'getNews' here because I registered a route for accessing my custom post type called news.
Whenever I encounter code snippets on the web, I see something like
Meteor.subscribe('posts', 'bob-smith');
The client can then display all posts of "bob-smith".
The subscription returns several documents.
What I need, in contrast, is a single-document subscription in order to show an article's body field. I would like to filter by (article) id:
Meteor.subscribe('articles', articleId);
But I got suspicious when I searched the web for similar examples: I cannot find even one single-document subscription example.
What is the reason for that? Why does nobody use single-document subscriptions?
Oh but people do!
This is not against any best practice that I know of.
For example, here is a code sample from the github repository of Telescope where you can see a publication for retrieving a single user based on his or her id.
Here is another one for retrieving a single post, and here is the subscription for it.
It is actually sane to subscribe only to the data that you need at a given moment in your app. If you are writing a single post page, you should make a single post publication/subscription for it, such as:
Meteor.publish('singleArticle', function (articleId) {
return Articles.find({_id: articleId});
});
// Then, from an iron-router route for example:
Meteor.subscribe('singleArticle', this.params.articleId);
A common pattern that uses a single document subscription is a parameterized route, ex: /posts/:_id - you'll see these in many iron:router answers here.