I am newbie to contentful and I have written an android application which uses content delivery API to fetch the content from my space.
I have used Vault and normal API (without vault) to fetch the content.
I observe that there is always a 3-5 seconds of delay in fetching the delta changes (new and update content).
My requirement is to give a real time data sync.
Is this an issue with my implementation or its an expected behaviour from contentful.
Sample code:
1. Using Vault
Vault.with(App.getInstance(), SampleSpace.class).requestSync(
SyncConfig.builder()
.setClient(ClientProvider.get())
.setInvalidate(false)
.build());
List<SampleTable> appointments = Vault.with(App.getInstance(), SampleSpace.class)
.fetch(SampleTable.class)
.where(SampleTable$Fields.DATE+"=?", mDateToCheck)
.all();
Normal API
private final CDAClient client = CDAClient.builder().setToken(CDA_TOKEN).setSpace(SPACE_ID).build();
client.observe(CDAEntry.class).all()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Action1<CDAArray>() {
#Override
public void call(CDAArray entries) {
//business logic here
}});
Thanks for your time and help!!
I'm a maintainer of the Java and Android SDKs in Contentful.
There could be some reasons for the slowdown:
1) You are syncing a lot of data
This would mean, that a lot of data, potentially even different pages have to be fetched from Contentful, parsed, serialised and put into the database in the Vault case.
In this case taking a look at fetching the entries by id and not using sync might be an idea. Sadly you would loose the niceness of Vault model classes and would need to implement the mapping from Contentful models to your custom models yourself.
2) ClassLoader.getResources
In your code snippet, you are recreating a CDAClient or Vault with every sync call. This has a known issue on Android and we are currently working on fixing it.
For now, till an update is out, the recommendation is to try and see if storing Vault and/or the CDAClient in a field might be helpful for subsequent calls.
3) The network is slow
Sadly this would mean, there is nothing we can do from our side ... ;)
I hope this gives you some pointers, on a solution, please feel free to report back with any progress you encounter.
The only solution I find to this issue is to use Contentful Preview API.
So when some object is modified/deleted/created, the response speed will be the same. That being said, the user can get every update in one second or less in the app/web.
The problem is the app will be showing entries that are published or not (draft),so it depends on the project requierements.
In case the user needs to use this solution, he must use the Content Preview API - access token which is in APIs top panel section in Contentful. I hope it helps!
Related
I have a collection in my Firestore Database with posts. Each post has some comments as a document in the collection comments in the main post document (screenshot)
In my Android app when I click on the post item I go to PostDetail screen and there I download comments.
I want to increment the value of timesViewed for each comment which has been downloaded and displayed.
Is it possible to do that? I want to do that in the most efficient way. I don't want to increment every single comment manually by sending a request timesViewed++.
I want to increment the value of timesViewed for each comment which has been downloaded and displayed.
If you're looking for something that does that automatically, please note that there is nothing built-in.
Is it possible to do that?
Yes, but you should implement your own mechanism.
I don't want to increment every single comment manually by sending a request timesViewed++.
Unfortunately, there is no other way. However, it is very easy to implement. You can use FieldValue.increment(1).
Unfortunately, such a feature does not exist in the RealtimeDatabase firebase and firestore to automatically increase a field.
But you can create a counter and retrieve the counter every time onResponse () or onComplete and increase it by 1, which is not recommended for 2 reasons.
Generates extra traffic, especially if the number of users is large
It is not reliable because someone can intentionally increase it
But if you do not mind a lot of traffic and you insist on doing so, do not forget to set rules in the firebase console to control the incremental frequency.
I'm building an Android app which syncs data to Google Fit and uses the Google Fit SDK to achieve that - but I'm pretty sure my question also applies when you are using the REST API.
Within my app users can also change data inserted to Google Fit. The Google Fit SDK has two distinct functions to handle those kind of things: insertData() and updateData().
Now, I don't want to keep track of whether a user changed an already synced data point vs whether it is an entirely new datapoint. I just want to have a simple Boolean flag which indicates whether a data point has already been uploaded to Google Fit or not - that's to keep things simple and reliable on the app's side.
So when a user creates a new data point in my app, I set a syncedToGoogleFit flag for that data point in my DB to 0. When the data point has been synced to Google Fit I set it to 1. When the user later changes the data point in my app I set it to 0 again and so on.
However, the Google Fit SDK distinguishes between inserting and updating which means a simple Boolean wouldn't be enough to track changes on my end as insertData() will fail if there already is a data point for a given timestamp. Is it possible to always call updateData() even if I am actually inserting new data and that way get by with just the Boolean flag on my end?
Looking at the documentation it should be okay, but I would feel safer if someone could confirm that. Also I'd like to know whether there are any potential performance implications of the approach outlined above, but I guess this is just something the SDK devs can answer.
I've played around quite a bit with the SDK now and from what I am seeing I can say, that using updateData() seems to work just fine.
Working with Firebase for the first time and looking for advice of setting up the right structure for my project which is basically an "offers/coupon" type starter project.
The scenario is this:
I have a node containing a list of all offers available to users
This list of offers is displayed to users after successful Firebase authentication
When a user redeems an offer, I want to be able to count/record that activity in their child node under user and hide that offer so that they cannot see it again once used.
My question is what would be the best way to do this given that offers may be added, may expire, or may change at some point in the future. So, in effect, the user should receive the list of most updated offers, minus the ones he/she have used in the past.
a) would it be more effective to have a master list of offers, and then run a cloud/server function to clone this list for each new user an track that way
Firebase Structure 1
or
b) Keep a master list of offers in one node, then track user specific offer usage
Firebase Structure 2
Appreciate your guidance
The second solution is better because you'll save bandwith. This practice is called denormalization and is a common practice when it comes to Firebase. The first solution is not good becase every time you want to display the users you donwload unnecessary data. If you want to read more details about how you can structure a Firebase database in a efficient way, please read this post, Structuring your Firebase Data correctly for a Complex App. Also, you can take a look a this tutorial, Denormalization is normal with the Firebase Database, for a better understanding.
Second solution is much good. Because in first one we are having redundancy of data in our database. And second one obviously removing that cause.
But instead of using true or false because it is only showing you, "it's available or not", so you can use a string type parameter as "expired", "going to expire" and "updated" or whatever sooo. So it. Will be able to trace all you information related to offer for particular user. I think this is your requirement also.
Happy coding.
I am creating one Google Fit compatible App. My objective is to store Google Fit data using HistoryApi, and provide kind of Back Up- Restore functionality to user. If user buys new Android devices then he/she should be able to BackUp(sync) old data using his/her account.
I need to use Custom Data Type, as Public Data Types doesn't meet my requirements.
Everything works perfect, I am able to insert data and read data using History Api.
But When I try to read data from Another Android device using same Google Account then data is not available to read there.
My problem seems similar to this Custom DataTypes not synching between devices
This statement from Google Fit Document is not clear to me.
Custom data types are not available to use in other apps. Only the app
that creates a custom fitness data type can use it
source : CustomDataType
Q-1) What does it really means ? If I have an app GoogleFitDemo installed on multiple Android devices, then is it possible to sync data between this same app between multiple Android devices ?
Q-2)Is it improper way to store and backup data using Google fit ?
Update:
Finally, I found that Custom Data Type can also be synced normally, same as other Public Data Types. I had the sync issue as mentioned by #Ifor. Sync functionality is still buggy. In some scenarios sync stops working, and sometimes synced data is inconsistent across multiple devices.
1). My understanding is that same app same account but different devices it should work. Having said that sync is notoriously slow (hours days...) and has been buggy so it may be hard to tell if you have it right or not.
2) There are better backup methods... But if the data fits in with the rest of the stuff Google Fit is about and is not too big then it's probably ok.
I currently have several fragment tabs , each with a feed of user statuses, being I have about a 100 other users posting from their accounts there is constantly new data every few minutes. currently the users only choice is to switch fragments back and fourth to get the entire fragment to reload which sends another http request and returns the new data as well as all the old data the user already had. it just doesnt seem efficient, know there has to be a better way. Can someone give me a overview of the most efficient way to keep this data fresh without having the user switch tabs back and fourth?
Is this where using sqlite and/or services comes into play?
Though some developers and designers argue between if content should be refreshed automatically of not, I argue content like streams shouldn't be refreshed automatically unless you are expecting very less incoming data.
I have used twitter4j to stream tweets and refresh automatically in one of my test app, twitter4j has a listener that lets you know when new tweets are received. First I pushed data into ListView as soon as new feeds were received and it was kind of flashy but, efficient. Then I queued up data until it reached certain threshold and pushed data into ListView, it was bit better. I thought it was good enough but, when I monitored my "Data Usage", i quite realized why I shouldn't refresh automatically.
Now here are some example implementation:
(Suggest) Do some type of polling or I recommend you to implement
push(like GCM) to let your client-side know that there's new content
in the server.
(Option) Use SyncAdapter with server triggered sync
(Recommend) Let user be in control, it's more than okay to use
Pull-to-Refresh pattern like Facebook or ActionBar sync button like
Google+. It will not make UserExperience any bad.
Now here's how your sample request API should be like or you can match your own config:
{
"fromIndex": 0,
"toIndex": 10
...
}
well, i'll try to give you a general overview to see if you can get it without the need of getting into deepest details, an idea it just came to my mind:
1- you need to configure your server to retrieve from an "specific" point of the content or retrieve a token that you will pass to the server (on next HttpRequest) to know from where part of the content or from where "index" start to send the content again.
2- you need to have a Listener (i dont know how you are showing your data but this is the case of a ListView) that tells you when the user is closely to get to the end of the ListView and let't say if there are already 10 elements, in element 7 the Listener should call the method to get more content from the server.
3- Yes, you need to keep the data already retrieve in SQLite temporarily, you can't use SharedPreference to keep it because it probably would be a lot of data and maintain it in memory could be a bad idea, writing a file is not an option here neither, so SQLite is your best friend in this case.
Maybe there would be more problems specifics about what you are trying to achieve but to me in a general perspective, those 3 points should at least help you in the direction to go.