Query problem using sembast (NoSql) with flutter - android

I'm very new to NoSql databases, and I just want to ask you an easy question about the use of sembast! I'm developing a very simple app with flutter, and I want to get the object inside the array "list" with the "name" equal to 1.
{
"id": 12345,
"list": [{
"name": 1,
"element": [{
"nameItem": "a"
}, {
"nameItem": "b"
}]
}, {
"name": 2,
"element": []
}, {
"name": 3,
"element": []
}]
}
So I want to make a query that retrieves me this information:
{
"name": 1,
"element": [{
"nameItem": "a"
}, {
"nameItem": "b"
}]
}
I've written this code, but it doesn't work: I don't understand how to make a query with a subtag as a key in the json tree.
Future<List<ElementList>> getElementFromList(int name) async{
final finder = Finder(filter: Filter.equals("name", name));
final recordSnapshot = await _elementList.find(await _db, finder: finder);
return recordSnapshot.map((snapshot){
final elementObj = ElementList.fromJson(snapshot.value);
return elementObj;
}).toList();
}
this returns me []. How can I solve the problem?
Thank you in advance!

Sembast queries allow to filter records, not part of a record. If the object you mention is a whole record, you can:
use custom filter to perform the lookup yourself for each record in the database (checking each item in the list field`)
when a record is retrieved, extract the item (doing a similar Map/List manipulation)
See an issue with a complex filtering

Related

How to insert nested json into SQLite Flutter

I want to make a categories screen, the backend returns a nested json with 4 trees in total if I'm not mistaken,
example:
when I press the most general tree of the categories, I would like it to be displayed as a dropdown and there, put the children of this category, the ones that come in the json clearly, hope to explain myself well.
I have to fill these widgets, their text or titles with the text that comes clearly in the json, but I'm not going to be calling the endpoint every time I want to paint the titles, i have to save what comes in the json in the sqlite, and then extract from there the texts to put on categories screen ... how can I do this? I'm new, never build a structure like that, I have to do it with sqlite, but I wouldn't know how to start or how to build the tables, if I make a table, only the first tree of the categories will go, and the rest? the children of the nested json? Could someone guide me?
I leave you a piece of the json (for other reasons I can not put it complete) to put them a little more in context
{
"res": 0,
"categorias": [
{
"id": 1,
"name": "Bolsas",
"img": "hogar.png",
"titulo": 0,
"children": [
{
"id": 11,
"name": "Para llevar",
"img": "llevar.png",
"titulo": 0
},
{
"id": 12,
"name": "Para Conservar",
"img": "consrvar.png",
"titulo": 0
},
{
"id": 13,
"name": "Para Organizar",
"img": "organizar.png",
"titulo": 0
},
{
"id": 14,
"name": "Multipack",
"img": "multipack.png",
"titulo": 0
}
]
},
{
"id": 2,
"name": "Cuidado del aire",
"img": "aire.png",
"titulo": 0,
"children": [
{
"id": 21,
"name": "Instantaneo",
"img": "instantaneo.png",
"titulo": 0,
"children": [
{
"id": 211,
"name": "Aerosol",
"img": "llevar.png",
"titulo": 0
},
{
"id": 212,
"name": "Toque",
"img": "consrvar.png",
"titulo": 0
}
]
},
You have several option to work with json and sqlite:
Just put your json as string in row on table and then select as string and convert to json.
You can use similar approach from paragraph 1 bud with using sqlite's json extension. It adds possibility to select of update parts of json by special query syntax. To use sqlite with this extension u will need custom build of sqlite like sqlite-android (with have many other benefits).
You can crate separate sqlite table from each level fo json nesting (depends on your need of granularity). For example you can create table categorias with columsn(categorias_id, categorias_name, categorias_img, categorias_titulo), table categorias_childrens with columns(categorias_id, id, name, img, titulo, categorias_childrens_id).
In this case all rows of categorias_childrens table related with categorias.categorias_id contains categorias.categorias_id in categorias_childrens.categorias_id column. And all rows related with some of categorias_childrens row contains categorias_childrens.categorias_id in categorias_childrens.categorias_childrens_id column (situation when children.id.21 has childrens ).
Or u can combine approaches fro example: create table categorias with columsn(categorias_id, categorias_name, categorias_img, categorias_titulo, children) where column children will be contains string json value.

How to get children with a value not equal to 0

Consider the following JSON format in Firebase database -
"root":
{
"question":
{
"1":
{
"category":"A",
"replies":0
},
"2":
{
"category":"B",
"replies":1
},
"3":
{
"category":"B",
"replies":0
},
"4":
{
"category":"C",
"replies":2
}
}
}
For getting all questions with replies = 0, I do,
Query query = rootReference.child("question").orderByChild("replies").equalTo(0);
which works perfectly.
But what should I do if I want those questions with replies not equal to 0 ?
Reading the documentation, I see no notEqualTo() method or any other way to "negate" a query. However, since you're already calling .orderByChild("replies"), you could perhaps use this:
Query query = rootReference.child("question").orderByChild("replies").startAt(1);
Firebase currently supports only positive operations, not the negation.
so you may want to retrieve all the data and then filter it locally.
Here is full answer
Actually Firebase doesn't provide any method to exclude some results like you are seeking here.
However, you can modify your JSON like this & then use following query:
// add a different key for all replies = 0, & another different key for non-zero replies
"root":
{
"question":
{
"1":
{
"category":"A",
"replies":0,
"key2":"someOtherKey"
},
"2":
{
"category":"B",
"replies":1,
"key1":true
},
"3":
{
"category":"B",
"replies":0,
"key2":"someOtherKey"
},
"4":
{
"category":"C",
"replies":2,
"key1":true
}
}
}
// now you can use this query to get all non-zero-replies results
// it will give you child 2, 4
Query query = rootReference.child("question").orderByChild("key1").equalTo(true);
// to get all zero-replies childs, use this
Query query = rootReference.child("question").orderByChild("key1").equalTo(null);

Firebase add item to array dynamically

I am trying to make some kind of comments using Firebase for Android.
Just have one question, are there any way to add new items to array?
For example, if I have such kind of object
If I am trying to push, it will convert it to map
And I don't want to overwrite this object each time, because I will have multiuser support and it will fail at some point.
And I am trying to do it as a List to do not create DataTransferObjects for my models, and to support auto parsing using firebase.
Thanks! If there will be no ideas will go with creating Maps, actually.
My ObjectModel:
public class Company implements Parcelable {
private String id;
private String name;
private String description;
private List<Comment> comments;
}
Code for pushing item:
final DatabaseReference ref = companiesRef.child(companyId).child(NODE_COMMENTS).push();
return Single.create(e -> ref.setValue(comment)
.addOnCompleteListener(task -> {
e.onSuccess(task.isSuccessful());
}));
This is how it works, look at the example below I have stored "0" as my first commentID and "1" as my second commentID. As you can see, I stored the lastCommentID as the commentID for the last comment in the lists.
{
"comments": {
"0": {
"text": "mycomment",
"time": "142351516"
},
"1": {
"text": "secondcomment",
"time": "153426564"
}
}
"lastCommentId": "1"
}
So whenever you want to add new comment to the firebase you have to retrieve the lastCommentID first as a string and convert it to integer(E.g. 1) then add 1 to the value(E.g. 2) so that when you save the next comment it won't override the previous version.
Note that you have replace lastCommentID each time you add comment to the database.
{
"comments": {
"0": {
"text": "mycomment",
"time": "142351516"
},
"1": {
"text": "secondcomment",
"time": "153426564"
},
"2": {
"text": "thirdcomment",
"time": "153426564"
}
}
"lastCommentId": "2"
}
You do not need to have a Model Class to write in Firebase, you can parse a JSON to Java Objects dinamically with Jackson and push it into Firebase.
You can parse a JSON as Java Objects with Jackson
. For example you can obtain: Object, List, Hashmap, Integer, String,
etc. without POJO classes.
To see more please visit this answer

Dynamic object creation with Retrofit

I am not that skilled with Retrofit library and I ran into a problem that i don't know how to handle without restructuring the whole project.
Basically, i have two responses that are very similar, but my code only handles one response.
Here are the responses and what i did, so tell me if there is any way to do this...
{
"cv":[
{
"id":46,
"name":"Ciriculum Vitae",
"description":"Lorem ipsum description is the best description one can write down",
"file":"1482915089-test-test-cv1.pdf",
"file_url":"http://xxxyy/file/46/1482915089-test-test-cv1.pdf",
"type":"cv"
},
...
],
"diploma":[
{
"id":52,
"name":"dasdasdasdsa",
"description":"Random description",
"institution_name":"hello",
"completed_date":"12.12.2016.",
"file":"1482918005-test-test-dasdasdasdsa.pdf",
"file_url":"http://xxxyy/file/52/1482918005-test-test-dasdasdasdsa.pdf",
"type":"diploma"
}
],
...
"certification":[
{
"id":50,
"name":"Certificate of Greatness",
"description":"I have been great at many things so everybody diecided to give me a certificate for it.",
"institution_name":"Certification 3",
"validation_date":"10.06.2017.",
"file":"1482917772-test-test-dasdasdasdsa.pdf",
"file_url":"http://xxxyy/file/50/1482917772-test-test-dasdasdasdsa.pdf",
"type":"certification"
}
],
...
}
Okay this is just a sample, but you can clearly see that these are some documents that have their types. There are 17 types of documents each with different fields.
Logically, I've created 17 different models cv model, diploma model, etc...
The problem arises later in the project when i want to fetch documents that are related to a single candidate, the response then is like so:
Response2
"documents": [
{
"id": 46,
"name": "Ciriculum Vitae",
"type": "cv",
"description": "Lorem ipsum description is the best description one can write down",
"file": "1482915089-test-test-cv1.pdf",
"file_url": "http://xxxyy/file/46/1482915089-test-test-cv1.pdf"
},
{
"id":52,
"name":"dasdasdasdsa",
"description":"Random description",
"institution_name":"hello",
"completed_date":"12.12.2016.",
"file":"1482918005-test-test-dasdasdasdsa.pdf",
"file_url":"http://xxxyy/file/52/1482918005-test-test-dasdasdasdsa.pdf",
"type":"diploma"
},
{
"id": 50,
"name": "Certificate of Greatness",
"type": "certification",
"description": "I have been great at many things so everybody diecided to give me a certificate for it.",
"file": "1482917772-test-test-dasdasdasdsa.pdf",
"file_url": "http://xxxyy/file/50/1482917772-test-test-dasdasdasdsa.pdf"
}
]
}
Now obviously the field 'type' is the type of object that needs to be created. But so far i don't know how to make my models fit into this 2nd response.
What should i do here, guys?
In case you're wondering what my code looks like, here it is...
#SerializedName("cv")
#Expose
private List<Cv> cv = null;
...
#SerializedName("diploma")
#Expose
private List<Diploma> diploma = null;
...
#SerializedName("certification")
#Expose
private List<Certification> certification = null;
EDIT
Actually what i wanted to do is create object dependent on the 'type' parameter and fill it with info i get from the response.
How will i go about doing this?

How to write and read contents containing complex json data?

friends:
I get a response from remote server as follows on Android:
{
"items": {
"persons": [
{
"id": "200120",
"name": "Bill"
},
{
"id": "200121",
"name": "Jim"
}
],
"tasks": [
{
"id": "001",
"name": "Fetch ten books",
"deadline": "5:30 p.m.",
"scores": "10"
},
{
"id": "002",
"name": "Fetch thirty books",
"deadline": "5:30 p.m.",
"scores": "30"
}
],
"intro": "This is a funny game."
},
"otherObj": []
}
And I want to save it to phones. I do not think it a good choice to save it into databases. However it read not fast if put the response to SharedPreferences file. Is there any other way?
No need to save this data into database as these value are dynamic and will change time to time.
In your Activity, call the API and get JSON as response and then parse this JSON and show it on device.
To store it on device u can use Singleton class also.
For JSON parser refer to http://www.tutorialspoint.com/android/android_json_parser.htm
You can first save your data into objects and at last into Object Array and then Save to database.(If your data is dynamic it is better you only deal with Object not database)
For saving to database you can use
db.beginTransaction();
for(object : ObjectArray){
db.dboperation();
}
db.setTransactionSuccessful();
db.endTransaction();

Categories

Resources