Implement visitor count with Firebase Database - firebase-realtime-database

Trying to implement a basic visitor counter that should increment whenever users click on a post. My method properly does that but the problem is counter increments whenever the same user clicks so it should happen only once. I have tried to handle this with booleans but did not work. Can anyone help please?
The counter part of my code.
private void incredmentCount(){
boolean isCounting = true;
if (isCounting){
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("posts").child(postId);
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("counter", counter++);
myRef.updateChildren(hashMap);
//stop counting as soon as database updates.
isCounting = false;
}
}

Since isCounting is a local variable, it gets initialized to boolean isCounting = true; each time you call incredmentCount.
If you want to keep the value across calls, you'll need to move the variable out of incredmentCount, for example make it a field in the class.
If you want it to stay saved across program runs, you could store it in shared preferences.

Related

Is StateNotifierProvider only for when you update the UI?

In Riverpod, if you have a class that has dynamic state, but you don't need to display changes to the state in the UI, do you use a StateNotifierProvider or just a plain Provider? Because StateNotifierProvider provides a hook to update the state of the class. What about if we manually update the state of a plain Provider, like:
final personProvider = Provider<Person>((provider) {
final person = Person(name: 'Bob');
return person;
});
Then elsewhere we update its state:
ref.read(personProvider) = Person(name: 'Joe');
Then elsewhere we rely on that state but do not display it in the UI:
// Will this be Bob, or Joe?
final dataToSaveToDatabase = ref.watch(personProvider);
Will Riverpod keep track of the state changes over time, such that if somewhere else in the app accesses said state with watch or read, it always gets the latest state?
Another way to frame this question is, "Is a StateNotifierProvider only used if you need to update the UI?"

How to use scoped_model with Shared Preferences?

I am add state management to my chat app using scoped_model.
My question is how use scoped_model with shared preferences. So on app startup Model state is fill with values from shared preferences. For example stored username will be retrieve from shared preferences and then store in UserModel username state.
I have look but no find tutorial how to do.
I have find this sample from FlutterCinematic main.dart:
void main() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
runApp(ScopedModel<AppModel>(
model: AppModel(sharedPreferences), child: CinematicApp()));
}
Is this best way to do?
What is best way?
Thanks!
I know it's been a while since this question was asked. But I am still gonna' answer it anyway.
I had the same problem when I was developing an android app using shared preferences and scoped model. My idea was to initialize the values in scopedmodel when the app starts. And the way I did it was to call the function within the constructor of the model.
Let's say my scoped model is:
class AppModel extends Model {
String variable1;
String variable2;
int variable3;
//Getter functions go here
//Setter function (though not a pure setter but a function that sets the values)
void setValues() {
SharedPreferences.getInstance().then(
(prefs) {
variable1 = prefs.getString('var1');
variable2 = prefs.getString('var2');
variable3 = prefs.getInt('var3');
));
}
AppModel(
setValues();
);
}
Now when you initialize the model before the Material app, its values will get initialized.

grails getPersistentValue() value changes without saving

I am using the getPersistentValue() method to determine how a property changed. However I've discovered that this method returns different values even if I have not explicitly saved the object.
Here's what I've narrowed it all the way down to...
trip.properties=[start:params.startmile,
end:params.endmile,
satusFlag:params.statusFlag,
description:params.description
];
// print statusFlag for checking
log.debug(trip.getPersistentValue('statusFlag')+":"+trip.statusFlag);
def driver=driverService.getValidDriver(params.driver,params.date);
//the persistent value of statusFlag has changed!!!!
log.debug(trip.getPersistentValue('statusFlag')+":"+trip.statusFlag);
The service call is just another criteria search to return a driver if he/she was employed at a date
def driver=Drivers.createCriteria().get{
and{
eq('id',id);
eq('division',division);
le('startDate',compareDate);
or{
ge('endDate',compareDate);
isNull('endDate');
}
}
};
return service
For some reason this query in a service forces my other objects to update their persistent values? Can someone explain why and how to avoid this?
I was able to solve this by importing the transaction annotation
import org.springframework.transaction.annotation.Transactional
and then adding
#Transactional(readOnly = true)
before the method that was being called.
However this won't work in all cases because not all service calls will be read only.

BreezeJS editing data not working

I was able to follow the instruction on adding data, that part was easy and understandable. But when I tried to follow instructions for editing data, I'm completely lost.
I am following the todo sample, which works quite well, but when I tried to add to my own project using the same principle, nothing works.
in my controller, I have the following:
function listenForPropertyChanged() {
// Listen for property change of ANY entity so we can (optionally) save
var token = dataservice.addPropertyChangeHandler(propertyChanged);
// Arrange to remove the handler when the controller is destroyed
// which won't happen in this app but would in a multi-page app
$scope.$on("$destroy", function () {
dataservice.removePropertyChangeHandler(token);
});
function propertyChanged(changeArgs) {
// propertyChanged triggers save attempt UNLESS the property is the 'Id'
// because THEN the change is actually the post-save Id-fixup
// rather than user data entry so there is actually nothing to save.
if (changeArgs.args.propertyName !== 'Id') { save(); }
}
}
The problem is that any time I change a control on the view, the propertyChanged callback function never gets called.
Here's the code from the service:
function addPropertyChangeHandler(handler) {
// Actually adds any 'entityChanged' event handler
// call handler when an entity property of any entity changes
return manager.entityChanged.subscribe(function (changeArgs) {
var action = changeArgs.entityAction;
if (action === breeze.EntityAction.PropertyChange) {
handler(changeArgs);
}
});
}
If I put a break point on the line:
var action = changeArgs.entityAction;
In my project, it never reaches there; in the todo sample, it does! It completely skips the whole thing and just loads the view afterwards. So none of my callback functions work at all; so really, nothing is subscribed.
Because of this, when I try to save changes, the manager.hasChanges() is always false and nothing happens in the database.
I've been trying for at least 3 days getting this to work, and I'm completely dumbfounded by how complicated this whole issue has been for me.
Note: I'm using JohnPapa's HotTowel template. I tried to follow the Todo editing functionality to a Tee.. and nothing is working the way I'd like it to.
Help would be appreciated.
The whole time I thought the problem was in the javascript client side end of things. Turned out that editing doesn't work when you created projected DTOs.
So in my server side, I created a query:
public IQueryable<PersonDTO> getPerson(){
return (from _person in ContextProvider.Context.Queries
select new PersonDTO
{
Id = _person.Id,
FirstName = _person.FirstName,
LastName = _person.LastName
}).AsQueryable();
}
Which just projected a DTO to send off to the client. This did work with my app in fetching data and populating things. So this is NOT wrong. Using this, I was able to add items and fetch items, but there's no information that allowed the entitymanager to know about the item. When I created an item, the entitymanager has a "createEntity" which allowed me to tell the entitymanager which item to use.. in my case:
manager.createEntity(person, initializeValues);
Maybe if there was a "manager.getEntity" maybe that would help?
Anyways, I changed the above query to get it straight from the source:
public IQueryable<Person> getPeople(){
return ContextProvider.Context.People;
}
Note ContextProvider is:
readonly EFContextProvider<PeopleEntities> ContextProvider =
new EFContextProvider<PeopleEntities>();
So the subscribe method in the javascript checks out the info that's retrieved straight from the contextual object.. interesting. Just wish I didn't spend 4 days on this.

ASP.NET MVC - HttpRequestWrapper.Url is null?

My application sends out some emails, and the image paths referenced in the e-mails need to vary depending on how the user accessed the page that is sending the email. I've used variations of the code before many times with no problem, but this is the first time I'm trying to do it in an MVC app:
var relImagePath = controllerContext.HttpContext.Response.ApplyAppPathModifier("~/Emails/Images");
var absImagePath = new Uri(controllerContext.HttpContext.Request.Url, relImagePath).AbsoluteUri;
The second line is throwing an NullReferenceException because HttpContext.Request.Url is null. How can that be?
Edit: I should note that I'm running this code in a thread pool thread separate from the one that processed the request. If I move this code back onto the thread executing the controller action, the url is there. For now, I've resorted to executing the code on the same thread.
The HttpContext might not always be accessible in threads. You will need to pass the required information to the thread:
var relImagePath = controllerContext.HttpContext.Response.ApplyAppPathModifier("~/Emails/Images");
var absImagePath = new Uri(controllerContext.HttpContext.Request.Url, relImagePath).AbsoluteUri;
new Thread(state =>
{
var imagePath = (string)state;
// TODO ...
}).Start(absImagePath);
or if you are using the ThreadPool (only for short running tasks):
ThreadPool.QueueUserWorkItem(state =>
{
var imagePath = (string)state;
// TODO ...
}, absImagePath);
I would suppose that RequestContext grabs current HttpContext at the time you call controllerContext.HttpContext (since it asks RequestContext for the HttpContext), and I suppose that it may just ask HttpContext.Current, and that's why get null.
Try to grab controllerContext.HttpContext in the ASP.NET thread, save it and pass to your own thread, instead of controller context which asks for HttpContext at wrong time later.
That's my guess.
Also, http://csharpfeeds.com/post/5415/Dont_use_the_ThreadPool_in_ASP.NET.aspx
This override also seems to work:
protected new UrlHelper Url
{
get { return base.Url ?? (base.Url = new UrlHelper(ControllerContext.RequestContext)); }
set { base.Url = value; }
}

Resources