Serialise / deserialise model in firestore - android

I have the following class that I want to store in firestore.
public class User extends Model {
#PropertyName("user_auth_id")
public String authUid;
#PropertyName("first_name")
public String firstName;
#PropertyName("last_name")
public String lastName;
#PropertyName("picture_url")
public String pictureUrl;
#PropertyName("email")
public String email;
#PropertyName("companies")
public ArrayList<UserCompany> companies;
public User() {}
}
public class UserCompany extends Model {
public String name;
public String role;
public String position;
public UserCompany() {
super();
}
public UserCompany(Company company, String role, String position) {
this();
name = company.name;
this.role = role;
this.position = position;
}
public Map<String, Object> toObject() {
Map<String, Object> object = new HashMap<>();
object.put("id", id);
object.put("name", name);
object.put("role", role);
object.put("position", position);
return object;
}
}
#IgnoreExtraProperties
public class Model {
#Exclude
public String id;
public <T extends Model> T withId(#NonNull final String id) {
this.id = id;
return (T) this;
}
}
And I want to use a transaction to update an user entry with it's newly created company list. (appUser instanceOf User)
transaction.update(userRef, "companies", appUser.companies);
If I do so...I get
Invalid data. Unsupported type: ro.exemple.model.UserCompany
How can I serialise an User object so that I can deserialise it as such
User appUser = queryDocumentSnapshots.getDocuments().get(0).toObject(User.class);
Where queryDocumentSnapshots is the result of a query in my firestore db.
I know I can change from ArrayList to HashMap, but I wish to keep the List, and try to serialise and deserialise it, in order to obtain in firestore an array of objects.

if this serialization you must tag your class as Serializable..
public UserCompany extends Model implements Serializable
public class User extends Model implements Serializable
plus tag the class Model as well

Related

How to Save Foreign Keys in Room Database

I have the following Model class that i want to store in Room Database:
I don't know much but i think i need to use foreign key here. Though i dont have much idea, its just a guess.
If you can give a detailed explanation,
public class EarthquakeData {
public List < Feature > features;
public class Feature {
public String type;
public Properties properties;
// public Geometry geometry;
public String id;
public class Properties {
public double mag;
public String place;
public Object time;
public Object updated;
public Object tz;
public String url;
public String detail;
public int felt;
public double cdi;
public double mmi;
public String alert;
public String status;
public int tsunami;
public int sig;
public String net;
public String code;
public String ids;
public String sources;
public String types;
public int nst;
public double dmin;
public double rms;
public double gap;
public String magType;
public String type;
public String title;
}
}
}
I have saved only a simple class in Room database like the following class:
#Entity(tableName = "notes")
public class Note {
#PrimaryKey
#NonNull
private String id;
#NonNull
#ColumnInfo(name = "note")
private String mNote;
public Note(#NonNull String id, #NonNull String mNote) {
this.id = id;
this.mNote = mNote;
}
#NonNull
public String getId() {
return id;
}
#NonNull
public String getNote() {
return this.mNote;
}
}
But i don't know to save the first type of model class in Room which is very complex for me because it consists of objects within a class.
From what I understand you have the following relationships:
1 EarthquakeData - Many Features
and
1 Feature - 1 Properties
So you could model it this way:
Table Features(id: PrimaryKey, earthquake_data_id: ForeignKey, ...)
and
Table Feature(id: PrimaryKey, properties_id: ForeignKey, ...)
With Room entities this would look something like this for the features:
#Entity(
tableName = "features",
foreignKeys = [
ForeignKey(
entity = EarthquakeDataEntity::class,
parentColumns = ["id"],
childColumns = ["earthquake_data_id"],
onDelete = ForeignKey.CASCADE, // See documentation for other operations
onUpdate = ForeignKey.CASCADE
)
]
class Features {
...
}
Check out the ForeignKey official documentation for the parameters

How to insert data and retrieve data in nested relationships in Room Database Android

I have entities
#Entity
public class A {
#PrimaryKey(autoGenerate = true)
public long id;
public String bFId;
public List<B> bList;
}
#Entity()
public class B {
#PrimaryKey #NonNull
public String id;
public String oneCId;
public List<C> cList;
}
#Entity
public class C {
#PrimaryKey #NonNull
public String id;
public String value;
}
And I wrote this like a Relation
public class AWithB extends A{
#Relation(parentColumn = "id", entityColumn = "bId")
public List<BWithC> bWithC;
}
public class BWithC {
#Embedded
public B b;
#Relation(entity=C.class,parentColumn="bFId",entityColun="cid")
public List<C> {}
}
Is my relation wrong? And How to insert data And retrieve data this.I must to be used this relation.I cannot use another relation.Please help me.

Realm query with child arrays

Here's the Object I'm working with:
public class NavigationMenuModule extends RealmObject implements Parcelable {
#PrimaryKey
public String sectionKey;
public RealmList<ItemModule> modules;
public RealmList<Article> spotlightSponsored;
public RealmList<Article> items;
}
The child Article Object:
public class Article extends RealmObject {
#PrimaryKey
public String contentId;
public String leadImageURL;
public String summary;
public String headline;
}
How would I structure this realm call:
get NavigationMenuModule item by sectionKey
get spotlightSponsored within that NavigationMenuModule that matches the article's contentId
The method below works but I feel like there's probably a "neater" way:
public static Article getArticle(String sectionKey, String articleId) {
Realm realm = Realm.getDefaultInstance();
NavigationMenuModule navigationMenuModule = realm.where(NavigationMenuModule.class).equalTo("sectionKey", sectionKey).findFirst();
if (navigationMenuModule != null && !navigationMenuModule.spotlightSponsored.isEmpty()) {
for (Article article : navigationMenuModule.spotlightSponsored) {
if (article.getContentId().equals(articleId)) {
Article ret = realm.copyFromRealm(article);
realm.close();
return ret;
}
}
}
realm.close();
return null;
}
Theoretically this should work with Realm 3.5.0
public class NavigationMenuModule extends RealmObject implements Parcelable {
#PrimaryKey
public String sectionKey;
public RealmList<ItemModule> modules;
public RealmList<Article> spotlightSponsored;
public RealmList<Article> items;
}
public class Article extends RealmObject {
#PrimaryKey
public String contentId;
public String leadImageURL;
public String summary;
public String headline;
#LinkingObjects("spotlightSponsored")
public final RealmResults<NavigationMenuModule> spotlightSponsoredOf = null;
#LinkingObjects("items")
public final RealmResults<NavigationMenuModule> itemsOf = null;
}
public static Article getArticle(Realm realm, String sectionKey, String articleId) {
return realm.where(Article.class)
.equalTo("contentId", articleId)
.equalTo("spotlightSponsoredOf.sectionKey", sectionKey)
.findFirst();
}

How to deserialize to arraylist with annotations

I need deserialize a string(json) to a arraylist inside a model. I'm using the Jackson-Annotation library to do this. Anyone can help me?
I've tried this, but doesn't work:
#JsonDeserialize(as = Model.class)
private ArrayList<Model> model;
or:
#JsonDeserialize(as = ArrayModel.class) //ArrayModel extends arrayList<Model>
private ArrayList<Model> model;
Sample:
public class Model extends BaseModel {
#JsonProperty("id")
private int id;
#JsonDeserialize(as = ModelTwo.class)
private ArrayList<ModelTwo> modelTwo;
public ArrayList<ModelTwo> getModelTwo() {
return modelTwo;
}
public void setModelTwo(ArrayList<ModelTwo> modelTwo) {
this.modelTwo = modelTwo;
}
}
I've solved this!
You need say the type of Object and the type of content.
After this, you need create a new Json with properties on params.
On first model:
#JsonProperty("property")
#JsonDeserialize(as=ArrayList.class, contentAs=ModelTwo.class)
private List<ModelTwo> modelsTwo;
On second model:
#JsonCreator
public ModelTwo(
#JsonProperty("id") int id,
#JsonProperty("name") String name) {
this.id = id;
this.name = name;
}

nested json parsing for android with jackson

i just started to android prograamming and found nice tutorial by using imdb api. instead of using xml in this tutorial i would like to use json and for the recevied json i have a problem.
this is the person.json:
[
{
"score":1,
"popularity":3,
"name":"Brad Pitt",
"id":287,
"biography":"test",
"url":"http://www.themoviedb.org/person/287",
"profile":[
{
"image":{
"type":"profile",
"size":"thumb",
"height":68,
"width":45,
"url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w45/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
"id":"4ea5cb8c2c0588394800006f"
}
},
{
"image":{
"type":"profile",
"size":"profile",
"height":281,
"width":185,
"url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w185/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
"id":"4ea5cb8c2c0588394800006f"
}
},
{
"image":{
"type":"profile",
"size":"h632",
"height":632,
"width":416,
"url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/h632/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
"id":"4ea5cb8c2c0588394800006f"
}
},
{
"image":{
"type":"profile",
"size":"original",
"height":1969,
"width":1295,
"url":"http://d3gtl9l2a4fn1j.cloudfront.net/t/p/original/w8zJQuN7tzlm6FY9mfGKihxp3Cb.jpg",
"id":"4ea5cb8c2c0588394800006f"
}
}
],
"version":685,
"last_modified_at":"2013-02-16 07:11:15 UTC"
}
]
my two object for them:
public class Person implements Serializable {
private static final long serialVersionUID = 6794898677027141412L;
public String score;
public String popularity;
public String name;
public String id;
public String biography;
public String url;
public String version;
public String lastModifiedAt;
public Profile profile;
}
public class Profile implements Serializable {
private static final long serialVersionUID = -8735669377345509929L;
public ArrayList<Image> imagesList;
}
public class Image implements Serializable {
private static final long serialVersionUID = -2428562977284114465L;
public String type;
public String url;
public String size;
public int width;
public int height;
}
ı couldnt figure out how to retrieve person list by using jackson object mapper.
when i use this one:
ObjectMapper mapper = new ObjectMapper();
Person person= mapper.readValue(jsonResponseString, Person.class);
i got:
02-16 18:34:48.010: W/System.err(376): com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.example.imdbsearcher.model.Person out of START_ARRAY token
02-16 18:34:48.180: W/System.err(376): at [Source: java.io.StringReader#40a81778; line: 1, column: 1]
02-16 18:34:48.554: W/System.err(376): at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:599)
02-16 18:34:48.830: W/System.err(376): at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:593)
i have changed the retrieve method with advice of Keith and crdnilfan.
but now i have a problem with the attribute of profile.
i realized that i am missing that one in person object and basicly i have created new profile object and moved imageList to this class.
i have updated POJO's as above.
but now i am getting the same error for the profile.
Can not deserialize instance of com.example.imdbsearcher.model.Profile out of START_ARRAY token
You need to deserialize the list, as your JSON is an array:
List<Person> people = mapper.readValue(
jsonResponseString, new TypeReference<List<Person >>(){});
However, after you do that you will have some additional deserialization errors because of the profile property in your JSON. Checkout: http://jackson.codehaus.org/1.5.7/javadoc/org/codehaus/jackson/annotate/JsonIgnoreProperties.html
Update:
public class Person implements Serializable
{
public List<Object> profile;
public String score;
public String popularity;
public String name;
public String id;
public String biography;
public String url;
public String version;
public String last_modified_at;
}
There are several ways to deal with this. This will give you a linked hash map for Profile.
Alternatively, if you control the JSON format, change the profile syntax to this:
"profile":[
image:...,
image:...
]
That's because you are trying to deserialize a list of Person.class, not one instance. Create another class like this
public class PersonList extends ArrayList<Person> {}
and then use
ArrayList<Person> people = mapper.readValue(jsonResponseString, PersonList.class);
The other two answers clearly explain the reason for the error, it would get rid off the error and it will parse Person object. But for me it failed to parse image objects. With below POJO we can parse the specified json completely, without any issues even in the absence of
#JsonIgnoreProperties
or
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
POJO definition:
public class PersonList extends ArrayList<Person> {}
public class Person implements Serializable {
private static final long serialVersionUID = 6794898677027141412L;
public String score;
public String popularity;
public String name;
public String id;
public String biography;
public String url;
public String version;
#JsonProperty(value="last_modified_at")
public String lastModifiedAt;
public List<Profile> profile;
}
public class Profile implements Serializable {
private static final long serialVersionUID = -8735669377345509929L;
#JsonProperty(value="image")
public Image imagesList;
}
public class Image implements Serializable {
private static final long serialVersionUID = -2428562977284114465L;
public String id;
public String type;
public String url;
public String size;
public int width;
public int height;
}
This should parse the json
String jsonResponseString = readJsonFile("person.json");
ObjectMapper mapper = new ObjectMapper();
PersonList person= mapper.readValue(jsonResponseString, PersonList.class);
or
List<Person> person= mapper.readValue(jsonResponseString,
new TypeReference<List< Person>>(){}); //if we use this we dont have to define PersonList class

Categories

Resources