Allow the user to acces a specific function only once a day - flutter

What if I want to make a page resets itself at 12:00 am or after specific time.
Let's say I want the user to use a specific functionality once every day. For example, if the user click on a button will sees a pic of a dag, and after 12:00 am the user can click on the button again to see another picture of another dog in a specific list of dogs' pics stored in the app. How this is can be implemented in Flutter?

Definitely there are different ways to do it. Assuming you'd like to handle the logic in the client side, you can store a local boolean value called 'seen' in the SharedPreferences.
Then somewhere in your app (startup for example), you can update the value to false if the time is after midnight. Assuming you already have SharedPreferences setup and it's in a variable called sharedPreferences
DateTime time = DateTime.now();
String resetTime = "${time.year}-${time.month.toString().padLeft(2,'0')}-${time.day.toString().padLeft(2, '0')} 00:00:00";
if(time.isAfter(DateTime.parse(resetTiem){
sharedPreferences.setBool('seen', false)
}
Now on the other side of the code, where the user clicks to see the picture, you can check if the sharedPreferences value is true or false in order to show the picture.
if(sharedPreferences.getBool('seen')){
return SomeWidgetWithThePicture;
} else {
return AnotherWidgetWithoutPicture // tell the user they can see it after midnight
}

Related

Flutter: Calling a function once in a lifetime of the flutter app

I want to call a function when app runs for the first time, which will ask the user to enter firstName , lastName and add a profile picture.
Once the above process is done the function will never again be called during the lifetime of the app.
For something like this you need to check if the user has already entered that data or not. If not then show him the page where he can enter information otherwise take him to HomePage. For this When the user enters the information you need to save it to some persistent storage and check it whenever the app runs. In this way, your function will be called only once until the user deletes the app or clear its memory. You could use the following libraries to store the data.
Hive,
Shared Preference
These libraries save the data in key-value pair and read data faster especially hive.
Use SharePreference
see below code snippet with little advancement in code you can achieve your result.
Future<bool> isFirstTime() async {
var firstTime = SharedPref.pref.getBool('first_time');
if (firstTime != null && !firstTime) {
SharedPref.pref.setBool('first_time', false);
return false;
} else {
SharedPref.pref.setBool('first_time', false);
return true;
}
}

How can I check if the user is playing the game for the first time?

I want to show a text for the first time running like "Hi, my name is NAVI." and then when the player will start the game again the next time it will another text for example "Welcome back."
Using player prefs is probably the easiest solution, though definitely not the only one*.
Due to the lack of boolean playerpref I usually opt to use SetInt/GetInt instead, but that's personal preference. You could also do it with a string or float.
private void Start()
{
if(PlayerPrefs.GetInt("HasLaunched", 0) == 0)//Game hasn't launched before. 0 is the default value if the player pref doesn't exist yet.
{
//Code to display your first time text
}
else
{
//Code to show the returning user's text.
}
PlayerPrefs.SetInt("HasLaunched", 1); //Set to 1, so we know the user has been here before
}
Playerpref stores values between sessions, so the next session will still have "HasLaunched" set to 1. This is however stored on the local device. so users can manually reset it if they'd really want to.
If you ever want to show the "first launch" text again, simply set HasLaunched back to zero, or delete it altogether with DeleteKey("HasLaunched");
*There are plenty of alternative solutions, like storing it in a config file locally, or using a remote database (this would be required if you don't want users to be able to reset it). They would however come down to the same principle. Setting a value to true or 1 somewhere, and checking that value on launch.

How do I "add" time to firebase timestamp in Swift?

This question is best stated in an example:
It is currently 9:00am. User wants to do activity at 4:00pm the following day. They use UIDatePicker to select 4:00pm the next day, and then hit a button. I know firebase does times in milliseconds from 1970, so what I want to do is "add" the number of milliseconds from 9:00am to 4:00pm the following day to the ServerValue.timestamp(), like so:
activitiesRef.child(newActivity.id).setValue([
"id": newActivity.id,
"name": newActivity.name,
"isActive": newActivity.isActive,
"locString": newActivity.locationString,
"locLat": newActivity.locLat,
"locLong": newActivity.locLong,
"privacySetting": newActivity.privacySetting,
"targetTime": ServerValue.timestamp()]) // + some added value of time
//"targetTime": [".sv": "timestamp"]])
The reason for this is because I will be displaying a countdown timer elsewhere in the app until it reaches the targetTime. If I can push to firebase the targetTime, then the countdown timer will be a simple comparison of the current time on the user's phone to the targetTime itself.
The error I keep getting when trying to add a double value to the ServerValue.timestamp() is "Contextual type 'Any' cannot be used with dictionary literal"
If it is not possible to do so, what other options do I have? Thank you.
ServerValue.timestamp() is not a number that you can use to perform date arithmetic. It's a special placeholder value that the server side interprets with its sense of time.
The best you can do is write the timestamp, read it back out as a number, then perform math on it.

How to update ion-toggle status real in time?

I have an ion toggle in my application that stores his status in a firebase Database, is there a way to change his status with the data loaded from firebase?
For example, if in the database the status is true, then when I load the view the toggle will be on. I've tried using checked:
<ion-toggle checked="status()" >
where status() returns a boolean.
But due to the async function of firebase, the view loads 1st before the value in status(). Can't find a solution to this problem so far, I'd apreciate any help.
Yes there's a way to do this, but using a function in your attribute is no good. When using a function in the DOM that returns a value you'll make that function executes every time there's a change in the DOM, so since this is a function that fetchs something on Firebase you'll make your user do an request to Firebase every time the DOM is updated.
A good way to do this is storing the Firebase result in a variable. you can do like this when you enter de page:
public myStatus: boolean;
// USING A LIFECYCLE HOOK
ionViewWillLoad(){
firebase.database().ref(`Path/To/Your/Status`).once('value', snapshot => {
this.myStatus = snapshot.val();
});
}
And in your HTML
<ion-toggle [checked]="myStatus">
<!-- You need to bind your checked attribute to myStatus, using checked="{{myStatus}}" also works -->
If you need to always check if your status has changed you can also create and observable on firebase, so if your status change you can change your toggle:
ionViewWillLoad(){
firebase.database().ref(`Path/To/Your/Status`).once('value', snapshot => {
this.myStatus = snapshot.val();
});
firebase.database().ref(`Path/To/Your/Status`).on('child_changed', snapshot => {
this.myStatus = snapshot.val();
});
// YOU'LL NEED BOTH SINCE THE FIRST LOADS THE STATUS FOR THE FIRST TIME AND THE SECCOND CREATES AN OBSERVABLE FOR WHEN THE STATUS CHANGE.
}
Hope this helps.

How do I reset a variable at the start of each day?

I have a variable that keeps track of user statistic I want to reset at the beginning of each day. How can I do that?
Since the application is not allowed to run in the background, it seems I will have to do the check every time the application is active but I don't know how to reset the variable I have only once. This is the function I wanted to use:
let beginingOfDay = NSCalendar.currentCalendar().startOfDayForDate(NSDate())
func resetCurrentTime(){
// Date comparision to compare current date and begining of the day.
let dateComparisionResult:NSComparisonResult = NSDate().compare(beginingOfDay)
if dateComparisionResult == NSComparisonResult.OrderedDescending || dateComparisionResult == NSComparisonResult.OrderedSame {
// Current date is greater or equal to end date.
currentTime = 0 //reset the time tracker
}
}
I wanted to use this function to check when the application is launched but the problem is that the application could be launched many time a day. How I can reset my variable only once at the beginning of a day if the user is using the application or when the application becomes active or is launched for the first time that day?
Thanks
You can store in the user defaults this value.
So the flow is the following:
When the app is launched or became active you check whether the value of the variable in the user defaults is the same as the current day (e.g. 25/07/2016), then do nothing.
If the value is different, then you update the value in the user defaults with the current day.
If the app is running and the date is changed, you can update the value of your variable by subscribing to this notification:
UIApplicationSignificantTimeChangeNotification