Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
My app is mostly used outdoors, so there is a Firestore load problem if there is no internet. When a user comes back home, he will have wifi but the app is closed and will not sync. Again when the user goes out and opens the app, there might not be an internet connection and the loop goes on.
What is the best way to sync Firestore in the background? There is BroadcastReceiver option but it is stated that WorkManager should be used instead. Also, there is LiveData but I can't find a Java example, so... what is best? (an example would be nice)
EDIT I had to delete some of the things because my question "is not focused enough"!?!?!?!
so there is a Firestore load problem if there is no internet.
There should not be any problems when the user has no internet connection, and this is because Firestore has its own default caching mechanism:
For Android and iOS, offline persistence is enabled by default.
You say:
When the user comes back home, he will have wifi but the app is closed and will not sync.
It won't sync unless you are listening for real-time changes. Besides that, it's always recommended to remove the lister according to the life-cycle of your activity. So if you are using addSnapshotListener() you attach a listener that gets called for every change that takes place in your database. So this is happening also when your app is closed. Not removing the listener might produce unwanted bills. So it's mandatory to detach the listeners before the activity gets destroyed. For more info, please check the following links:
How to set addSnapshotListener and remove in populateViewHolder in RecyclerView Item?
How to stop getting data in Firestore?
#1. It's not recommended to do that. However, JobDispatcher is old and deprecated, and no longer available, not the BroadcastReceiver class. But if need, you should use WorkManager instead. If you must absolutely use JobDispatcher, which I recommend against it, the source code is archived here. So please read about how to migrate from JobDispatcher to WorkManager.
#2.
Can I use test DB for production and change permissions to read-only? Does that test DB have an expiration date?
Each database has its own Security Rules. So you should choose to secure your data according to your needs. However, there is no expiration date involved, but you can use something like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.time < timestamp.date(2021, 08, 05);
}
}
}
To limit the access to the database until tomorrow, August 5th, 2021.
#3. You can use the database also without security rules. But most likely you should consider using them. Most likely you shouldn't use the username, nor the email address, but UID that comes from the authentication process.
#4. Yes, every CRUD operation counts against your free quota. And yes, there's a minimum of one document read, even if the query yields no results. So if your query doesn't return any results, you have to pay one document read.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Problem Statement:-
I have to design an application to handle Tasks. In this Task are created by the scheduler at regular interval. The task must be pushed to queue for further processing and persisted in the database. Users can view and reschedule the task.
How should I approach the problem to design the system.
In general, I would recommend either start by writing down in "sudo code" what you want the application to do or by creating a process diagram of a user creating a task and include steps describing what the system should do. Maybe before either of those, a good place to start is in a brainstorming session. I usually like to start with the five "W"s (okay, and I added an "H" at the end, but that doesn't roll off the tounge very well). The five "W"s are Who, What, Why, When, Where, and How.
Who will use the application? Regular people? Doctors? Lawyers? Teachers?
What do users need the application to do?
Why do users need the application to do those things?
When will users use the application? While they are at work? While they are driving a car or riding a bicycle?
Where will users use the application? On their mobile phones? One their desktop or laptop computers? On their tablets? On a refrigerator? (not joking on that last one, we have computers now on refrigerators)
I'm not sure if you want to build a web application, mobile app, or something else. To answer your question better more specific information is needed. But, in the mean time here's a tutorial on how to write an application to handle tasks (a todo app), which is written in Java.
https://youtu.be/RXtj4TxMmW0
And here's a tutorial showing how to create a to do app using Django:
https://medium.com/fbdevclagos/how-to-build-a-todo-app-with-django-17afdc4a8f8c
And here's a tutorial showing how to create a to do app using React:
https://scotch.io/tutorials/create-a-simple-to-do-app-with-react
Another great tool to get you started is either a white board, or just a bunch of paper, a pencil, and lots of erasers. Sometimes the easies way to begin is just jotting down your ideas on paper. Once the "creative juices" start flowing and you have so many ideas on paper that you are running out of room, it sometimes helps to group similar ideas together. It sometimes then makes sense to combine ideas together to form one bigger idea. Then try to identify of all the things you want your app to do, which are the most important and put them in order of priority.
Out of your brainstorming try to figure out what data is needed in order to make your application work. For example, a todo app might have a ToDo data element. It might also have a User element, which each ToDo element might be owned by. For each data element, also called an Model, Table, or a Entity (all three of these things are the same, just different names) try to figure out what attributes are needed in each model. For example, the User model might have the attributes: username, password, email_address, first_name, and last_name. The ToDO model might have the attributes: name, description, is_complete, and completed_date_time.
And maybe look around at other ToDo applications to see how they work and get more ideas. Best of luck with your ToDo app!
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have two questions:
How to handle events, like user logged in etc.
Let's say I have repository and I am calling a Repo.function in my viewModel, and that ViewModel.method is called in my activity, when user presses the button. So, in some time my Repo.method completes and returns 200, and says my user is logged in. The question is, how my android view ( activity / fragment ) should now that it has to navigate? Currently I use EventBus to post and subscribe to such events.
How to handle network loading states: default/loading/completed
Currently I have a separate singleton that has ObservableFields for loaders like val isTokenLoading = ObservableField(false)
In my viewModel I hold ref to that singleton.isTokenLoading
My view binds to that viewModel's field
And in this way I handle UI changes during loading progress
What is the best way to do such things?
For your first question, I would say that the Observer pattern is the way to go (and the one people usually choose). For instance, RxJava fits perfectly in your use case, and you can even use it with LiveData nowadays. You would launch the request on your ViewModel, create an Observable from the response, perform all the operations you need, and do one of the following: subscribe to the final Observable on your view, or subscribe to a LiveData on your view, while updating it through the observable subscription on your ViewModel (I prefer the latter since it keeps the RxJava dependencies out of the view). You have tons of examples online with implementation details on this.
As for your second question, you're already using the Observer pattern (which, again, is the way most people do it), but keeping all loading fields in the same class seems to me like a code smell. It would probably be better to store them on the class that has to deal with them.
Edit: I just came across an article on AndroidPub exploring exactly what you want: https://android.jlelse.eu/android-architecture-communication-between-viewmodel-and-view-ce14805d72bf
you should use observer pattern. your repository can return a flow (in kotlin coroutine package) and you can observe this flow in you viewmodel. then you can expose this flow to a live data and observe this live data in your fragment or activity. using live data will help you to avoid memory leak.
for handling network states you can have another live data and post state of network to that. and of course observe it in view if you want.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Suppose there is a some system where rows in a database are filled when something happens:
when user simply logs in, a row is inserted to the database with type of login and time in table user_logins.
when operator make a call to the user, a row with operator id, user id and date insertted in database in table outgoing_calls
when operator does not answer to user call, a row with date, user id, and type call inserted into the database
Then after some time period is over, say month, we need a report on who called to who, how many calls were not answered, etc. What pattern should be used to organize this functionality?
At first glance this process seems like logging a lot, but logging is a process when we store a message with some format (date-processId-messageWithPlaceHolders). So using logging system for that is not very suitable.
From another point of view it looks like event processing, but it is not necessary to do any actions when "event" happens, no listeners, no queues. Just storing to database for further reporting.
So what pattern or technique should be used to implement this functionality effectively?
Your requirement is to to generate a who-called-who report monthly so that you can, e.g., understand the success of your calls (or whatever reason you have).
You don't need to think about resemblance to logging or event processing or anything. Just analyze the problem from top down to get the least amount of work you need to accomplish your task:
You need to generate a report monthly
For this you need to run a job which generates result at least once a month
For this you need to store your events in a format that can be understood by your job.
So a good solution is to have a batch job run monthly. This can be a manually run java process, a cron job, a hadoop task, ... depends on your technology stack. Your events need to be stored at the time their happen. Again, depending on your stack, it can be a relational database, a key value store, a file with log lines..., whatever is the easiest to work with in your technology stack.
All of these options can be good ones, but some are probably better. E.g., I recommend against using pure string logging. You need to extract structured attributes like time, numbers, etc. so prefer a format which helps you keep type safety.
I'd use the just-implement-it-in-your-business-service pattern:
void login(User user) {
entityManager.persist(new UserLogin(user));
}
void call(Operator op, User user) {
entityManager.persist(new PhoneCall(op, user));
}
void missedCall(User user, Operator op) {
entityManager.persist(new MissedCall(user, op));
}
That's assuming your business service is notified if a call is missed. If mere absence of an answer should trigger the database update, i'd turn the logic around and record successful answers instead:
void answeredCall(UserCall call, Operator op) {
entityManager.merge(call).setAnsweredBy(op);
}
and report the calls where call.answeredBy is null.
In either case, I'd do the reporting by querying the database.
Alternative
If most operations in your business service need to be so recorded, I might automate this using an AOP interceptor.
I am creating an app that checks for user locations every half an hour and updates the location of the user in the local database and then runs CRUD queries based on the user's location even when the app is not running. How do i do it ?
I have referred to this http://techtej.blogspot.com.es/2011/03/android-thread-constructspart-4.html article and i am still confused about which is the correct approach for my result ?
There are 4 options according to the article for what i intend to achieve according to me
1) Service : But since i feel it would be a long operation with the local database, i feel i should ignore this one.
2) IntentService : This cannot perform multiple tasks, so i feel this one also should be avoided for me as i have to get the location of the user and scan the database , update the database (3 tasks)
3)Thread : I am not sure how to call this when the app is not open
4) AsyncTask : I am not sure how to call this when the app is not open.
Basically i looking for something like a CRON JOB that runs on a local database while working on the location data.
It would be great if you could link me up to some tutorials and answer with a simple example to make me understand the difference of all 4 methods.
// editted on 16 March :
I have read something about a JobScheduler which is introduced in the API 21, but not sure if it also supports till Gingerbread and is it the right approach for my question
Thanx
When recording the users position use a service with a notification. Just for the sake of creating a morally responsible app that informs the user the app is tracking them. The service by definition runs in the background.
A fused location provider with setinterval(long) 30 minutes gets the interval. Set fastestInterval() to a minute to receive GPS data when other apps are using the GPS.
Have you considered using a SyncAdapter. Its best to schedule jobs at fixed interval and also optimized for battery usage. Also, once started, it can run independently of the app. As per your requirements, I believe this is best suited for your need. You can read about this here. This also removes the corner case of starting the service (generally used) when your device is restarted. Your app will still continue running the scheduled job even if the device gets restarted.
In the SyncAdapter you have to use a ContentProvider so wrap your DB inside a ContentProvider. Also, preferably use a CursorLoader to run longrunning tasks on DB. You should read about CursorLoader. This is a great way to access your resources. Also, you can define an Observer Design Pattern which Observes for changes in a DB and will perform a task when changes are made in DB. This can also be used inside your application itself and also inside SyncAdapter. Cursor Loader is best preferred for background work on DB. You can perform all CRUD Operations using a CursorLoader and ContentProvider.
This cannot perform multiple tasks
Yes, it can. It has only one thread, and so it can only do one simultaneous task.
i have to get the location of the user and scan the database , update the database (3 tasks)
I have no idea why you think that is three tasks. You cannot do them simultaneously.
Your bigger problem with IntentService is that getting location data is asynchronous, and IntentService is not well-suited for calling APIs that themselves are asynchronous.
But since i feel it would be a long operation with the local database, i feel i should ignore this one.
The point behind any service is for "a long operation".
Basically i looking for something like a CRON JOB that runs on a local database while working on the location data
Use AlarmManager to trigger a WakefulBroadcastReceiver, which then triggers a Service. The Service, in onStartCommand(), forks a background thread to (asynchronously) retrieve the location and update the database. The Service can then call completeWakefulIntent() on WakefulBroadcastReceiver, plus stopSelf() with the startId received in onStartCommand() for this work, plus allow the thread to terminate. If no other commands were received in the interim, the service will shut down.
I think you are looking for something similar to WakefulIntentService. This handles all your cases completely.
You can do your location and db related work inside doWakefulWork() of said implementation.
I've done what you are looking for, both with GPS and non-GPS.
The project I took as staring point for the non-GPS solution already does all you need, and is battery-friendly (credits should go to Kenton Price):
https://code.google.com/p/little-fluffy-location-library/
Take a look at it, it works like a charm. Just run it in any device. If you need any help customizing just let me know.
Just edit the "onReceive" method in the "TestBroadcastReceiver" to update your DB.
If you need the GPS solution let me know too, but I dropped it for being a battery killer!
Hope it helps.
1. I think for this requirement, Thread and inside it AsyncTask -- this structure will be useful.
In link provided by you, it is mentioned very nicely here
2. For location related blog, you can check useful materials here :
(1) Difference between Google Map Distance and Directions API
(2) Check this answer also
Hope this will help you
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am working on an android App similar to Line/Whats app i.e. basically instant messenger. The problem I face is that even after the user logs out, The notifications are still displayed.
In other words, there is no way to disable the notifications once the user log outs. Instead, the notification are never disabled and keep on reoccurring even after log out making the app highly unusable.
Any advice would be greatly appreciated.
THanks
I imagine that the notifications are being displayed via a Service that receives the messages in the background. What I suggest is the following:
a) This should be the simplest, since the user is logging out, there is no more need to have the background service in the background, so you can make a call to stopSelf() when the trigger to log out is made. If the logout action is happening on an activity, you can notifiy the service via either a broadcast, or via a message, depending on how you've established your service.
b)If you want to try something else, you can add a flag to your service class: isUserLoggedOut and set it to true when you do the logout workflow. Then, you can check for this flag when deciding whether of not to notify the user.
private void showNotification () {
if (isUserLoggedOut)
return;
//shownotification otherwise
}
c) In all honesty though, I strongly advice to revise your logout workflow, to clear existing persistent data from that user (access tokens, etc), close the main activity for chats and display the logon activity again, and disable any processing of messages in the service, as your service shouldn't be handling messages for any account, assuming the user signed out.
Cancel all your notifications using the NotificationManager once the user logs out of your app.