I'm beginner in Android and I'm trying to understand how GAE works with Objectify.
So I've created two classes, one 'User' and another one 'Journey'. Each Journey belongs to a User.
User Class
#Entity
public class User {
#Id
private Long id;
#Index private String mac;
private String name;
private String firstName;
private Long age;
private String email;
private String password;
// Getters and setters
}
Journey Class
#Entity
public class Journey {
#Id
private Long id;
Key<User> driver;
private Event event;
private Long nbPlaces;
private String departureTime;
private String destination;
}
I've writed the following method on the User class, is this correct ?
#Transient
Key getKey() {
return Key.create(User.class, id);
}
How can I set the Key of the User in my Journey Object ? (I think I can't use a simple setter.
Thanks !
Previously declared:
import static com.googlecode.objectify.ObjectifyService.ofy;
To get the object:
public User get(Long id) {
return ofy().load().key(Key.create(User.class, id)).now();
}
And to set the Key from User into Journey class, you need to pass into the constructor when the object is created, or get the object Journey set the parameters and save it. But you need to get the Key previously:
public Long getKey(User user) {
Key<User> generatedKey = ofy().save().entity(user).now();
return generatedKey.getId();
}
After this, you can attach a list of Users into Journeyclass.
Related
I created an object to send some data to firebase. As an example, I use firebase user example:
public class User {
public String username;
public String email;
public User() {
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
public User(String username, String email) {
this.username = username;
this.email = email;
}
}
I want to encode property names that are sent to firebase. Currently keys are sent using variable names. I want to encode keys something like Useraname and Email, like Gson is doing. I don't want to change variable names.
#SerializateName("Username")
public String username;
#SerializateName("Username")
public String email;
I used #SerializateName(), but is not working. Same with #PropertyName that is used by Firebse, is not working. What I can use in order to serializare custom keys?
Update 1
public class Pojo {
#PropertyName("Guid")
public String guid;
#PropertyName("Name")
public String name;
public String getPojoGuid() {
return guid;
}
public void setPojoGuid(String guid) {
this.guid = guid;
}
}
As you can see in the image, it saves keys based on variable names. I changed property name from annotation for one field and when i save it, it ignores it, but when i change variable name, it save as new entry with key for that new varialbe name.
In this documentation is a method toMap(). If i do like that, is working (is not convenient for me), but is not working with #PropertyName.
Update 2
If i mark getters and setters with #Exclude and class with #IgnoreExtraProperties is working. I don't have to use toMap() method example from documetation. Is using specified name from #PropertyName. Not a good thing in my opinion, create confuses.
The Firebase SDK uses the annotation it finds for the property whenever it gets or sets its value. That means you need to consider how Firebase gets/sets the value, and annotate each place it looks.
Since you're declaring a getter method, Firebase will use that to get the value of the property. It will use the field for setting the value. So the annotation needs to be on both:
public class Pojo {
#PropertyName("Guid")
public String guid;
#PropertyName("Name")
public String name;
#PropertyName("Guid")
public String getPojoGuid() {
return guid;
}
#PropertyName("Guid")
public void setPojoGuid(String guid) {
this.guid = guid;
}
}
If you'd have getters and setters, the annotation would need to be on those, but not on the fields anymore:
public class Pojo {
private String guid;
private String name;
#PropertyName("Guid")
public String getPojoGuid() {
return guid;
}
#PropertyName("Guid")
public void setPojoGuid(String value) {
guid = value;
}
#PropertyName("Name")
public void setPojoGuid(String guid) {
this.guid = guid;
}
#PropertyName("Name")
public void setPojoGuid(String value) {
name = value;
}
}
What you are looking for is the feature of SDK Version 9.2 in which you can now use a new #PropertyName attribute to specify the name to use when serializing a field from a Java model class to the database. This replaces the #JsonProperty attribute.
#PropertyName("Username")
public String username;
#PropertyName("Email")
public String email;
See also this post in which Frank van Puffelen explains very clearly this concept.
#PropertyName :
Marks a field to be renamed when serialized. link
you have to use #PropertyName with public fields and no need for getters/setters
if I extends any object from ParseObject or ParseUser, it everytime returns me null for every variable it contains. For example:
public class User extends ParseUser {
private boolean emailVerified;
private String facebookID;
private int fiveHundredID;
private String fiveHundredUsername;
private String firstName;
private String lastName;
private String canonicalFirstName;
private String canonicalLastName;
private Date birthday;
private Photo profilePicture;
private int followeeCount;
private int followerCount;
}
And then I call User.fetchInBackground(), it doesn't fill any variable except objectId, email and the others variable, that are contained only in ParseUser class. Of course, I already initialize Parse in App class like:
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
Parse.enableLocalDatastore(getApplicationContext());
Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
.applicationId(Const.X_PARSE_APPLICATION_ID)
.clientKey(Const.X_PARSE_REST_API_KEY)
.server(Const.PARSE_SERVER_URL)
.enableLocalDataStore()
//.addNetworkInterceptor(new JsonInterceptor())
.build());
ParseObject.registerSubclass(User.class);
Im not using any proguard, because Im testing that on the Debug version. Any help? Also when I have enabled LocalDataStore, it store my current User. But when I call fetchInBackground(), it returns me the same data as Local data are stored. Also when I call unpinInBackground() and after that I'll call fetchInBackground(), it still returns me the local data stored in DB.
Any help?
Many thanks
Add this annotation just above your model class :
#ParseClassName("User")
public class User extends ParseUser {
...
Let's say I have a structure of realm-objects that looks like this -
public class Person extends RealmObject {
#PrimaryKey
private int id;
private String name;
private List<Pet> pets
// Setters, getters...
}
public class Pet extends RealmObject {
private String name;
private MedicalRecord record;
// Setters, getters...
}
public class MedicalRecord extends RealmObject {
private String something;
private String somethingElse;
// Setters, getters...
}
Now I received a new Person object with an existing id (primary-key) and I want to update this person.
So I do something like this -
realm.beginTransaction();
realm.copyToRealmOrUpdate(person);
realm.commitTransaction();
The trouble is that this person's pet list (and the pets' medical records), are still out there in the db. not linked anymore to this person, but still there.
I tried to do this -
Person existingPerson = realm.where(Person .class).equalTo("id", ID).findFirst();
existingPerson.getPets().clear();
But no success there. How can I remove subobjects of realmObjects?
Also, is there a way to define a policy for a realm-object so that it will remove itself once there is no reference to it (it's not linked to any parent-object)?
Now you can, and method was renamed from last commit to realmList.deleteAllFromRealm()
there is a problem when I use the Realm in Android.
I wrote two RealmObject.
public class Feed extends RealmObject {
#PrimaryKey
private long id;
private String content;
private long uid;
...
}
public class User extends RealmObject {
#PrimaryKey
private long uid;
private String name;
...
}
I want to search the result with:
[feed_id, feed_content, user_id, user_name ...]
should I need add a new Object ( FeedUser extends RealmObject) with these fields? Is this waste the memory?
Also I want to listen the change about user Object, if I add the FeedUser, when User changed. How to update FeedUser synchronous ?
thx :)
Take a look at how Relationships work in Realm.
If a user can have multiple Feed objects then you can have List<Feed> in your User object instead of defining user id yourself in your Feed. It will be something like this. You can read documentation more to see how you will get User with its feed in one query.
public class Feed extends RealmObject {
#PrimaryKey
private long id;
private String content;
...
}
public class User extends RealmObject {
#PrimaryKey
private long uid;
private String name;
private RealmList<Feed> feeds;
...
}
I have a JSON string that contains a nested json like
{
"name": "name",
...
...
"profile": {
"id": 987,
"first_name": "first name"
...
...
}
}
I'm trying to map this JSON into Realm by using the method realm.createObjectFromJson(Class clazz, String string) and the problem is that the nested JSON is not mapped, the resulting RealmObject instance that corresponds to the "profile" has 0's and null's for all the fields. I used realm.beginTransaction() before the create operation, and realm.commitTransaction() after.
I'm using 'io.realm:realm-android:0.80.1' for my Android project.
Can you please tell me what am I doing wrong?
Thanks.
EDIT
These are my model classes. Simple RealmObjects linked together
public class SomeClass extends RealmObject {
private String name;
private Profile profile;
public Profile getProfile() {
return profile;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
}
public class Profile extends RealmObject {
private String firstName;
private String lastName;
private String birthdate;
private boolean newsLetter;
private boolean push;
private int userId;
private Date lastUpdate;
private RealmList<RealmAddress> addresses;
private RealmList<RealmGender> genders;
}
the profile class contains only getters and setters, and it contains other Strings and ints, which I deleted for the sake of simplicity.
Your JSON names doesn't match your child object field names which is why you don't see any data. Your profile name matches the field in SomeClass, which means the object gets created (with default values), but as none of the fields match in Profile, none of them are set.
firstName != first_name
userId != id
If you want to have separate names in your JSON and the Java models you should use something like GSON (http://realm.io/docs/java/#gson) as that is not yet supported by Realm directly.
use this :
public class Profile extends RealmObject {
private String first_name;
private int id;
...
}
check that you have the same names in JSON and your class model