Flutter count number of page view and show it - flutter

I want to implement the number of views feature in my application with flutter.
The feature is the same as StackOverflow question view counter: it's persisted.
I was thinking of firebase analytics but I think it's not free to get data from there
Is there any way to do it?
Thanks in advance

The previous answer is correct but you should know it's not free.
The way I found to return analytics data is to use BigQuery which is in the BLAZE plan so I think you have to pay to get data from firebase analytics

To calculate the number of views in my recent app i used Firestore, which is Firebase's Database. Initialize the views as zero in your database and then write a function to increment the view every time the user views it.
How do you determine if the user viewed it?
Now that entirely depends on your application.

There is a short way instead if you just want to capture number of visitors on your webapp
I created a collection called "Visits" in firestore and generated auto id inside which I added a field called "count". That's it! Now you just have to call this method in your first screen's init method :
updateCounter() async {
final cRef = FirebaseFirestore.instance.collection('VISITS');
await cRef
.doc("mS9fCXjvkpREt8LvanSb")
.set({"count": FieldValue.increment(1)}, SetOptions(merge: true));
}

Related

How to handle statemanagment in flutter to listen to document changes in firestore?

Im building an app with a backend on firestore.
Architecture:
This is the relevant route of screens the user can take in my app:
Home-> myOrdersList(FutureBuilder)-> OrderInfo(FutureBuilder)-> HandleOrder.
to get the futures and handle my order I have this class:
class FirestoreService
functions:
Future List GetOrders;
Future Order getOrder;
Future void changeOrderInfo;
Order class:
class Order
parameters:
String info;
This is the problem:
When the calls FirestoreService().changeOrderInfo on HandleOrder-screen the screen pops to OrderInfo-screen. The SpecificOrder-screen automaticly rebuilds with setState so thats works fine and the changed info is up to date here. But when the user navigates one screen backwards in the stack to myOrdersList (where all current orders are listed) that screen still holds the old data that was fetched before the order was handled. So not before the user manually updates the screen you can se the current state and the changed info on that screen.
My question:
So I wonder if there is a simple stateManagement technique to solve this problem in a simple way. One way I have thought of is to use changenotifier in FirestoreService, and notifyallisteners when the function changeOrderInfo is called to then notify all relevant screens and get them up to date but I dont really know if thats correct. Since there are many orders and new ones are continuously created I cant simply listen on one document and provide those changes.
One solution could also be to use a streambuilder in myOrdersList but i dont like that solotion since it would mean that data would be fetched everytime any order was changed
if you are after real-time updates stream builder is the only way to go. unless you want to refresh your future builder again and again every time there is an update which will kill your wallet because that means you are refetching all the documents again and again. Unlike stream builder, you only fetch the collection once and if there is an update, it will only refetch the document changed/updated not the whole collection. check this out for more explanation https://firebase.google.com/docs/firestore/query-data/listen

Can iOS14 widget requests main app to update its data?

my app needs latest data but, possibly, the main app has old data.
so i want to request to the main app to update its data.
is it possible?
if it is not I would like to know any alternative way.
(should the widget requests latest data to the server??)
thanks
===
UPDATE
I found many tutorials and all of them use http request from getTimeline method for getting newest data (not from the main app). it is not what i want.
Someone said easest way for sharing data between main app and widgets is using UserDefaults. But the data can be old if the main app does not update userdefaults values or update values using old data. (beside server data is always latest data)
So what i want to know is the way 'widget makes main app updates its data and updates userdefault and call reloadTimelines. so widget can use latest data.
There's no way for a Widget to tell its parent App to refresh its data.
You can either:
fetch data directly in the Widget - see: How to refresh Widget data?
enable background notifications in the App (see How to run code when your app is terminated) and, when received one, force the Widget to refresh its timeline using:
WidgetCenter.shared.reloadAllTimelines()
In reality it's probably better to just fetch data directly in the Widget. This way you can fetch only the necessary data - Widget views usually display a lot less information than App views.
Yes, you can like this;
When you create a TimelineProvider for widget update, you have to implement this func,
func getTimeline(in context: Context, completion: #escaping (Timeline<Entry>) -> ())
This function waits to create your widget update timeline. You can sen a request, after the response, you can create a timeline and return func's completion.
You can configure an App Group and store the database in that shared group directory. That way, if you update data in the main app or in the widget, those new data are available for both, it's not necessary to call the other one to load the same data again. Just be aware that you should still use
WidgetCenter.shared.reloadAllTimelines()
after you updated the data in your main app to refresh the widget immediately. Just have some handling for when the last request was performed, so you don't create an unnecessary request in your widget, and instead fetch them from the database.
If you move your request-performing code into a modul, you can also use it in the widget, as you do in your app. Finally you'll just have another call of the same updating code you are used to from your main app.
Since I don't have any of your code to update and present here, I'll just link some helpful sources for the way to the described destination.
Apple Documentation: Configuring App-Groups
Sharing data within App-Groups

Caching Data ( Redundant API Calls )

I'm new to Flutter, and I've stumbled upon a problem I need advice in how to approach it. I'm building an app which uses navigator and flutter_bloc. Now when I navigate to a certain route I have the bloc state pull some data from an API and show it. What I want to achieve is not call the API every time when I navigate to that route unless the app has been closed previously or a "pull to refresh" action has been made. How do I got about storing the data after the initial API call. I've tried with the hydrated_bloc but either I don't understand the point of the hydrated_bloc well or it's intention is not to do that. Thank you for the advice in advance.
class AppState {
static final AppState _instance = AppState._internal();
factory AppState() => _instance;
ApiResponseCustomClass apiResponse;
AppState._internal() {
// init things here if needed
}
}
A simple way is to just make a state class where you will keep the result in, and then access it via AppState().apiResponse anywhere in your code.
You can use local_storage to maintain your data locally. So every time you need to fetch data from API again and again. and you can clear data before closing the app.

When should i use streams vs just accessing the cloud firestore once in flutter?

I want to create a groups functionality for my app, so far when i set up the profile page of each user, i've used something like this :
DocumentReference documentReference =
_firestore.collection("users").document("$email");
await documentReference.get().then((DocumentSnapshot datasnapshot) {
if (datasnapshot.exists) {
displayName=datasnapshot.data['displayName'].toString();
bio=datasnapshot.data['bio'].toString();
print(bio);
}
else {
print("No such user");
}
This works but im thinking if i want to create groups and record the changes that different users may make then i should probably use a stream is that correct? Generally i am unsure when to use which if anyone could provide some insight?
The technical difference is that get only gets the document once, while the stream will get the current data straight away, and then continue to listen for changes.
I typically use a stream (or its underlying onSnapshot()) when I display the data straight into the UI, because that means the UI updates whenever the data changes. This is one of the really cool Firebase features, because it makes your UI reactive to the data changes. I use get() for things that I only need once, such as configuration data (although it's also very cool if you use a stream for that), client-side joins, etc.
It all really comes down to whether you want the data to reload every time something changes in your database.
If you want it to update as it changes in your database, use a Stream (most likely with a StreamBuilder)
If you want it only to update when you reload the screen, use get() like you are in your example

How to make my pages in flutter persistent?

I want to make all my inherited pages persistent using flutter but I don't know how does anyone know how to accomplish this?
Given the fact that this cannot be answered properly without seeing your implementation, here is what a lot of developers do:
If you application is simple, store each state as a key-value pair. Then store that value and key inside shared preferences.
You would simply need to:
Add shared_preferences: "<newest version>" to pubspec.yaml
Synchronously update the key-value pair in-memory using prefs.setInt('currentState', value);. This persists the data to the disk.
Read your state data suing final counter = prefs.getInt('currentState') ?? 0; and accordingly update your setState method:
Now, this does infact assume that you have a simple application with simple states. If you have more complicated states and actions, then you should consider things like the BLOC pattern in order to organize your app in a way that enables a larger amount of control.