I am using eclipse to create a app engine based application where I am also using app engine datastore(using JPA) using endpoints.
I wrote a test application with help from
https://developers.google.com/eclipse/docs/endpoints-addentities
and it went fine.
Now I want to create an entity where I define my own Key rather than it being automatically assigned by the system. Can someone help me as to what do I need to do that in my Notes.java entity class. By default the Notes.java like this.
package com.bfp.mypackage;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Note {
#Id
private String id;
private String emailAddress;
private String description;
public Note() {
}
public String getId() {
return id;
}
public String getDescription() {
return description;
}
public String getEmailAddress() {
return emailAddress;
}
public void setId(String idIn) {
this.id = idIn;
}
public void setDescription(String description) {
this.description = description;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
}
When I test this code I see the Note entity created in my dev app server admin console with the values(an emailAddress, a dsescription and an ID(I pass timestamp there)) I had supplied. I see two other fields created when I view the entity in admin console. One "Key" and other "Write ops". Now the "Key" field as I understand is the one generated automatically by java. Is there anyway I can set my emailAddress field as the Key? If so then what changes I need to do in above code. That way I can use emailAddress as the unique key for each entity.
You must set your email address as the "Key" name : a key is defined by either an auto-incremented long ID, or a user assigned key name that is unique for an entity kind.
I'm not the most experimented using JPA since I've used mostly JDO and the low level approach, but you might have to use directly the com.google.appengine.api.datastore.Key object instead of a java.lang.String attribute...
The low level API method is :
KeyFactory.createKey("EntityName", "whatever#domain.com");
Related
There are two different apps that are connected to the same database. One is sort of an admin app that updates and deletes data in the database and the other is sort for the user app which only receives the data in the app. I have used the model class in the admin app to update and delete the data. I want to show this data in the user's app using firebase recycler but for which I require model class that was used how can I achieve that??
MY MODEL CLASS
package com.parth.iitktimes;
import java.io.Serializable;
public class Creator implements Serializable {
private String name,design,email,phone,downloadUrl,uniquekey;
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
public String getUniquekey() {
return uniquekey;
}
public void setUniquekey(String uniquekey) {
this.uniquekey = uniquekey;
}
public Creator(String name, String design, String email, String phone, String downloadUrl, String uniquekey) {
this.name = name;
this.design = design;
this.email = email;
this.phone = phone;
this.downloadUrl = downloadUrl;
this.uniquekey = uniquekey;
}
//empty constructor
public Creator() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesign() {
return design;
}
public void setDesign(String design) {
this.design = design;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
MY FIREBASE CONSOLE
images of firebase console
Architecture
enter image description here
Your question is not clear enough to answer correctly, but i think you are trying to access common classes of your app (like data model) from another.
You should consider using module for your project, generally speaking the code you write for your one app can't directly or indirectly access your other app's data and class even if both app is build by you.
(Technically it can access using reflection and other methods but you want to use same codebase)
There are many benefits of building modular app check out this 2019 IO talk
okay, so how you can access your common classes in both client and admin app?
create a new project (in android studio), create a new library module in same project, again create a new app module in same project.
what you got is two app and one library in one project, you can use that library as a dependency for both of your apps and write common classes in that library.
If I Right with the question,
In Firebase Project Overview......where you used firebase for Admin App and choose Add App...you can add User App to connect two app in single Firebase
I'm writing Android app with Room Database. My database contains GroupVc entity with such code:
#Entity
public class GroupVc {
#ColumnInfo(name = "language")
private String language;
#NonNull
#PrimaryKey
#ColumnInfo(name = "name_group")
private String nameGroup;
public GroupVc(String language, String nameGroup) {
this.language = language;
this.nameGroup = nameGroup;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
#NonNull
public String getNameGroup() {
return nameGroup;
}
#NonNull
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
As you can see my entity class contains two columns where nameGroup is my PrimaryKey. In my application I want to let the user to see the full list of groups and change the name of Group DialogFragments by entering new Group's names. To implement such function I've created the next DAO #Query method:
#Dao
public interface GroupVcDao {
#Query("UPDATE groupvc SET name_group= :newName WHERE name_group= :currentName")
void updateNameOfGroup(String currentName, String newName);
}
In this QUERY I want to change name of GroupVc by getting the existing name of GroupVc from RecyclerView (currentName param) and applying new one from DialogFragment (newName param).
My problem is that this QUERY doesn't bring any effect and doesn't update the name. Although I don't get any errors or exceptions. So I need to know: does such QUERY correct? Is it possible to write Update queries where primary key is changeable value and condition at the same time?
Here is the link to my complete project on GitHub
https://github.com/LAHomieJob/VocaNote
I can't be sure, but my guess would be that your query is working, but since you're changing the primary key your database is left with an instance of the old object as well as the new one. Try checking to see if you have an object with both the old name_group and the new name_group. Also if you're looking to allow your users to change the group name, it may make sense to move your primary key to a UUID or some other key that doesn't change.
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
I've been trying to add Realm in my Android app. Their docs are pretty well explained & easy to follow. But it fails to explain this one particular area. I'm unable to figure out the practical use for the #Ignore annotation. I know that fields under this annotation are not persisted.
Can someone please share a few use cases. Also I wanted to know the scope of such fields. I mean, if I set an #Ignore field to some value, would that value be available to the other classes in my app for that particular launch session. If yes, then how do we access it? If no (which I guess is the case), then why do we need such a field anyway?
I've searched here and on web but couldn't find the relevant information. If out of my ignorance, I've missed upon some resource, please guide me to it.
Thanks.
Accordingly to the official documentation (see https://realm.io/docs/java/latest/) #Ignore is useful in two cases:
When you use GSON integration and your JSON contains more data than you want to store, but you still would like to parse it, and use right after.
You can't create custom getters and setter in classes extending RealmObject, since they are going to be overridden. But in case you want to have some custom logic anyway, ignored fields can be used as a hack to do that, because Realm doesn't override their getter & setters. Example:
package io.realm.entities;
import io.realm.RealmObject;
import io.realm.annotations.Ignore;
public class StringOnly extends RealmObject {
private String name;
#Ignore
private String kingName;
// custom setter
public void setKingName(String kingName) { setName("King " + kingName); }
// custom getter
public String getKingName() { return getName(); }
// setter and getter for 'name'
}
Ignored fields are accessible only from the object they were set in (same as with regular objects in Java).
UPDATE: As the #The-null-Pointer- pointed out in the comments the second point is out of date. Realm now allows having custom getters and setters in Realm models.
Here's a couple of real-world use cases:
1 - Get user's fullname:
public class User extends RealmObject {
private String first;
private String last;
#Ignore
private String fullName;
public String getFullName() {
return getFirst() + " " + getLast();
}
Get JSON representation of object:
public class User extends RealmObject {
private String first;
private String last;
#Ignore
private JSONObject Json;
public JSONObject getJson() {
try {
JSONObject dict = new JSONObject();
dict.put("first", getFirst());
dict.put("last", getLast());
return dict;
} catch (JSONException e) {
// log the exception
}
return null;
}
I've found it useful to define field names for when I am querying. For example
User.java
public class User extends RealmObject {
#Index
public String name;
#Ignore
public static final String NAME = "name";
}
And then later on I can do something like:
realm.where(User.class).equalTo(User.NAME, "John").findFirst();
This way if the schema changes from say name to id I don't have to hunt down every occurrence of "name".
Please see the the official documentation about #Ignore annotation:
The annotation #Ignore implies that a field should not be persisted to disk. Ignored fields are useful if your input contains more fields than your model, and you don’t wish to have many special cases for handling these unused data fields.
I am using the .Net backend for Azure Mobile Service. I can successfully run the following query, and it returns all items from the database however it only returns the items with their IDs and no other columns are returns, they are all set to null
TableName.execute(new TableQueryCallback<ClassName>() {
#Override
public void onCompleted(List<ClassName> result, int count,
Exception exception, ServiceFilterResponse response)
So do I need to supply a select filter or should I be using the TableOperationsCallback? There is no error, it just returns all the columns as null except for the id column
Thanks
Make sure that the casing of the fields match between the client and the server. By default the .NET backend will make all properties camel-case, so that if you have this class:
public class Person : EntityData
{
public string Name { get; set; }
public int Age { get; set; }
}
Then the JSON response in a GET operation will look something like this:
[
{ "id":"the-first-id", "name":"John Doe", "age":33 },
{ "id":"the-first-id", "name":"Jane Roe", "age":34 }
]
So you need to define in your Android application a type where the field is either named in lower case, or properly tagged with the #SerializeName annotation, like in the example below (you don't need to do that for the id property as it's special-cased by the SDK):
public class Person {
#SerializedName("id")
public String Id;
#SerializedName("name")
public String Name;
#SerializedName("age")
public String Age;
}