I'm new to Android development but usually find the answer to my issues online. I've spent the whole weekend without success.
What I'm trying to do is read data from the JSON file on the internet.
It looks like this
[
{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "9246.27",
"price_btc": "1.0",
"24h_volume_usd": "5659320000.0",
"market_cap_usd": "156378808114",
"available_supply": "16912637.0",
"total_supply": "16912637.0",
"max_supply": "21000000.0",
"percent_change_1h": "1.77",
"percent_change_24h": "-1.51",
"percent_change_7d": "-17.57",
"last_updated": "1520773466"
}]
It's just a single object in an array. Unfortunately, it's not up to me how it looks like.
What I am successful at doing is reading HTML and then finding the fields I'm looking for but I want to do it in a better way. I've watched tens of videos and read some tutorials online but I just can't make it work. I get exceptions, crashes and what not and out of the rage deleted it all and I am starting from scratch again. I know beginner questions are not usually welcomed so I don't ever ask anything myself. I'm just doing this little project for fun to learn some programming.
It would be cool if somebody could show or point me in the right direction. I literally can't even read the data if I'm approaching it as JSON and not HTML.
Related
I'm no back-end developer. So perspective is always appreciated.
I have written a script which requests from an API and creates this huge JSON file I want to save in firebase, how can I accomplish this? And would it be possible to filter this json with python for example; when I add region=eu in the url this returns the objects which have Europe as region or do I absolutely need to request the entire json file and parse in my code (java android) ?
Since there are a few parts to your question:
You can save JSON to Firebase and the data will be mapped to child locations:
Using PUT, we can write a string, number, boolean, array or any JSON object to our Firebase database...When a JSON object is saved to the database, the object properties are automatically mapped to child locations in a nested fashion.
https://firebase.google.com/docs/database/rest/save-data
And for your next question:
And would it be possible to filter this json with python for example; when I add region=eu in the url this returns the objects which have Europe as region
Looks like you should be able to jimmy something together with Firebase's filters, startAt and endAt:
We can combine startAt and endAt to limit both ends of our query.
https://firebase.google.com/docs/database/rest/retrieve-data#section-rest-filtering
For your example you might do something like this:
curl 'https://yourfirebase.firebaseio.com/yourendpoint.json?orderBy="$REGION_NAME"&startAt="EU"&endAt="EU"&print=pretty'
...or do I absolutely need to request the entire json file and parse in my code (java android) ?
The facts that JSON objects are stored hierarchically in Firebase and that you can filter based on those object values makes me think you do not, in fact, have to request the entire JSON file. However, I don't have personal experience with this particular aspect of Firebase, so give it a shot!
As #ackushiw mentions in the comments, you can also use the equalTo query (https://firebase.google.com/docs/reference/js/firebase.database.Query#equalTo):
curl 'https://yourfirebase.firebaseio.com/yourendpoint.json?orderBy="$REGION_NAME"&equalTo="EU"&print=pretty'
It really depends on how you are structuring your JSON. It's generally recommended to make your JSON tree as shallow as possible since all children are loaded when you have a matching query.
FIREBASE DATA:
{
"-id1": {
"region": "eu" // bear in mind queries are case sensitive
"title": "Foo"
"nested": {
"city": "berlin"
}
},
"-id2": {
"region": "other"
"title": "Bar"
"nested": {
"city": "berlin"
}
},
"-id3": {
"region": "eu"
"title": "Baz"
"nested": {
"city": "paris"
}
}
}
Querying with (using the Android API)
.orderByChild("region").equalTo("eu")
would return "-id1" and "-id3"
with
.orderByChild("nested/city").equalTo("berlin")
would return "-id1" and "-id2"
The REST API Returns Unsorted Results: JSON interpreters do not enforce any ordering on the result set. While orderBy can be used in combination with startAt, endAt, limitToFirst, or limitToLast to return a subset of the data, the returned results will not be sorted. Therefore, it may be necessary to manually sort the results if ordering is important.
If you're using a more complex structure I recommend watching this video
https://www.youtube.com/watch?v=vKqXSZLLnHA
I'd also recommend using the firebase library for Android
https://firebase.google.com/docs/android/setup
And Firebase-UI, It does a lot for you.
https://firebaseopensource.com/projects/firebase/firebaseui-android/
I find Firebase Database sample very helpful, but I noticed something which worries me a little bit.
I mean in this example user can give star to the post, something like "Like it" on Facebook. In provided sample they nested stars into post, so we have sample object like this:
"post_id" : {
"author": "username",
"body": "Some content",
"starCount": 1
"stars" : {
"user_id_who_gave_star" : "true"
}
"title": "Some title",
"uid": "author_id"
}
Such solution has many advantages, like e.g. we can check if have already gave star and hide or change icon, or we can one transaction to change "starCount" and add next value to "stars".
But the problem is when we have big application and 1000 users gave star, so everytime when we download post data we download 1000 userIds which may be not best solution.
Question
My question is, what is best approach for such applications and have someone tested how Firebase works in this situation?
firebaser here
When writing the examples for our documentation, we always have to balance the need for having enough context, keeping the example small enough , and following our own best practices.
This is indeed one of the cases where we violate one of our own best practices "not nesting data". As you said: this means that a user downloading a post, gets all the UIDs of users that liked that post.
As the usage of the application scales, that may become a concern. If that is the case for your app, you should model the "users who upvoted a post" as a separate top-level node:
"posts": {
"post_id" : {
"author": "username",
"body": "Some content",
"starCount": 1
"title": "Some title",
"uid": "author_id"
}
},
"upvotes": {
"post_id" : {
"user_id_who_gave_star" : "true"
}
}
I'm looking for a way to create a JSON dynamic array that looks like this: {
"id": 1,
"name": "National Geographic Channel",
"image": "http://api.androidhive.info/feed/img/cosmos.jpg",
"status": "\"Science is a beautiful and emotional human endeavor,\" says Brannon Braga, executive producer and director. \"And Cosmos is all about making science an experience.\"",
"profilePic": "http://api.androidhive.info/feed/img/nat.jpg",
"timeStamp": "1403375851930",
"url": null
},
This needs to be generated in the cloud of Parse.com, and has to be based on Parse database then it needs to return a JSON array link that contains JSON arrays so I could be able later to use it on my Android application
If this method is not the best one to work with, could you please provide a better one.
I'm still a newbie in App developpement. Any help would be really appriciated.
Thanks.
https://parse.com/docs/js/api/classes/Parse.Query.html#methods_toJSON
I think your use of the term "dynamic" is confusing... nevertheless I think I understand. From what I can gather you're using Parse.com JavaScript Core SDK, you've created a Class, you want to pull from the object and convert it to JSON format (if so, see my example below).
or use my method...
Parse.initialize("appId", "javascriptKey", "masterKey");
var Blog = Parse.Object.extend("Blog");
var Query = new Parse.Query(Blog);
Query.find({
success: function(parseData) {
var dataString = JSON.stringify(parseData);
var jsonData = JSON.parse(dataString);
// now use jsonData
console.log(dataString);
console.log(jsonData);
},
error: function(parseData, error) {
console.log("Unable to query the Parse object");
}
});
I have a json file on server:
{"images":[
{"url":"...", "likes":"123"},
{"url":"...", "likes":"234"},
{"url":"...", "likes":"345"}
]}
I get the json file on android read it, but if someone likes a picture i want to change the value of the first picture from 123 to 124, is this possible and how can i do this?
The whole point is to change a json value on server,from client side.
Also if this isn't possible how can i make this happen?
Also if i want to get the Top50 rated pictures,how can i sort them and get only the 50 picture,without getting all pictures and sorting them on android ?
Which one is better,initializing the Top50 images,when the user starts the app,or when the user click on the button Top50.I assume that if its when he click the button,there might be some performance issues server side?
My other idea is to have a function server side,which every 10 min,executes automatically and gets the Top50 rated and makes something like json file.So it all happens server side automatically.
To make this happen, client should expose some interface, i.e. function that will allow to modify file on server side. The interface and implementation of this function greatly depends on server itself, i.e. which protocols it handles, what built-in or external modules it supports, which languages are supported, etc... For example, the classic scenario is using apache as HTTP server, CGI enabled, and write CGI function in perl. So, in this case interface would look like http://server.name/like.cgi?image=image123.
How to modify the values on the server ?
For this every like of a photo should be a post request of this sort.
{
"data": [
{
"image_id": 3133456,
"likes": 343
},
{
"image_id": 3133456,
"likes": 343
}
]
}
On parsing this request server updates the corresponding image's like on the server.
How to get the top 50 rated/liked images from the server ?
Again you send a get request to such a url
http://server.getsomething.com/getTop50Images
On server side
On receiving such a request you make a query on the table in your database something like this
select image_id , image_url, likes from image_table limit 50 ORDER BY likes ASC
Now getting those query results and returning them as a json would not be a performance hit until you have huge bulk of data. like some million rows may be in your database.
Response can be something like this
{
"result": [
{
"image_id": 3133456,
"likes": 34400,
"url": "http://flickr.com/someimage"
},
{
"image_id": 3133456,
"likes": 34380,
"url": "http://flickr.com/someimage"
}
]
}
You still avoid using a database yourself but can lease it from clouds services like parse.
However if you won't be using those services then you can take a look at ftp packages for js. Like the neo JavaScript library by apache.
But still a good choice will be to go with the database approach (is quiet simpler).
I have used XML to JSON converter from json.org. My problem is that the Boolean & integers are shown without double quotes in the converted JSON.
My JSON has to be sent to UI which uses Javascript for Cordova app for iOS & Android app. Since conversion in iOS retains the double quotes when converting from XML to JSON, in Android also I have to retain them. In iOS there is no way remove the double quotes during conversion.
e.g. XML snippet
<handle>
<price>20</price>
<item>chair</item>
<tax>true</tax>
</handle>
XML to JSON converter from json.org converts to
"handle": { "tax": true, "item": "chair", "price": 20 }
Expected to converted to following JSON
"handle": { "tax": "true", "item": "chair", "price": "20" }
Please let me know if there any other converting libraries/options using which this can be achieved?
Thanks in advance.
According to this:
https://github.com/douglascrockford/JSON-java/blob/master/XML.java#L303
No. At least not the 'easy' way. Either use a different library or use this to build the JSON you want, but do your XML parsing manually and use appendString when building the JSON.
That said, I'm not sure this is really what you want. You should reconsider why it is you need the "true" in string form, it seems highly likely to me that the real bug is somewhere else and this might be a way to avoid having to fix the real issue. Not judging you, I've been there before.