Obtaining the reference and key in Custom Object Firebase Android - java

I'm looking to pass the reference of the dataSnapshot and key of each specific object into a custom 'Message' object.
I've tried using the key 'String key' within the Message.class but it appears to come back null.
Here is how my Message object currently is:
public class Message {
private String key;
private String sender_id;
private String sender_username;
private String receiver_username;
private String receiver_id;
private String chat_id;
private String message;
private Firebase ref;
private double createdAt;
private boolean read;
public Message() {
// empty default constructor, necessary for Firebase to be able to deserialize messages
}
public String getKey() { return key; }
public String getSender_id() { return sender_id; }
public String getSender_username() { return sender_username; }
public String getReceiver_username() { return receiver_username; }
public String getReceiver_id() { return receiver_id; }
public String getChat_id() { return chat_id; }
public String getMessage() { return message; }
public Firebase getRef() { return ref; }
public double getCreatedAt() { return createdAt; }
public boolean getRead() { return read; }
}
Any ideas, how I properly pass the dataSnapshot.getKey() String to the custom object? I don't see an example on the Firebase docs, and to be clear I'm using the "legacy Firebase", before they updated.

When you get a Message instance from a DataSnapshot, you are likely doing:
Message message = snapshot.getValue(Message.class)
Since this is starting from getValue(), the message will not contain the key of the DataSnapshot.
What you can do is set the key yourself after reading the Message:
Message message = snapshot.getValue(Message.class);
message.setKey(snapshot.getKey());
You'll want to mark the getKey() as #JsonIgnore in that case, to ensure that Jackson tries to auto-populate or serialize it.

I ended up adding a static method to create the object from the DataSnapshot:
public static Message FromSnapshot(DataSnapshot snapshot)
{
Message msg = snapshot.getValue(Message.class);
msg.setKey(snapshot.getKey());
return msg;
}

Related

All my firebase field get automatically an underscore on front

My PoIs class:
public class PoIs {
private Integer location_id;
private String location_name;
private String location_address;
public PoIs() {}
public PoIs(Integer location_id, String location_name, String location_address) {
this();
this.location_id = location_id;
this.category_id = category_id;
this.location_name = location_name;
this.location_address = location_address;
}
public Integer get_location_id() {
return location_id;
}
public void set_location_id(Integer location_id) {
this.location_id = location_id;
}
public String get_location_name() {
return location_name;
}
public void set_location_name(String location_name) {
this.location_name = location_name;
}
public String get_location_address() {
return location_address;
}
public void set_location_address(String location_address) {
this.location_address = location_address;
}
I populate PoIs with informatision from a sqlite database:
final PoIs p = new PoIs(Integer.parseInt(row.get(0).toString()), row.get(1).toString(), row.get(2).toString());
and at a moment intend to save them on a firabase database:
FIREBASE_REFERENCE.child("PoI_"+ p.get_location_id()).setValue(p)
.addOnCompleteListener(t -> {
final boolean isSuccessful = t.isSuccessful();
final String msg = !isSuccessful
? getResources().getString(R.string.fb_error)
: getResources().getString(R.string.fb_success);
});
All work perfect except that my firebase fields start with an underscore. Instead location_id, location_name, location_address I have _location_id, _location_name, _location_address. I can't understand why this happening. Any ideea how to resolve this issue?
Firebase uses JavaBean naming conventions when mapping from properties in your code to properties in the database. In that convention a method like get_location_name is the getter for a property called _location_name.
If you want the property in the database to be location_name, that'd be a getter getLocation_name. Alternatively, you can use a #PropertyName("location_name")) annotation on all accessors (so the getter/setter function and/or the public field) to indicate the explicit property name you want in the database.

How to use serialization to maintain a file to store objects

I've looked at many places on serialization but can't seem to find a solution to my problem. I'm making an Email client program and I want to store every email I send as an object in a file and then be able to retrieve it.
The problem I encounter is that every time I use ObjectOutputStream's writeObject() method, it truncates the file instead of appending it. Then I tried storing the emails in an ArrayList and storing the ArrayList in the file. Like, everytime I want to store I would readObject() the ArrayList then add the new email to it and then write the ArrayList again to the file. But this method started throwing many exceptions(i.e InvalidClassException).
Is there a way to serialize objects such that I will be able to append them to the file each time I want to write a new email or any other workaround for this?
Thanks in advance, below is the EmailMessage class:
public class EmailMessage implements Serializable{//implement serializables
private String recipient;
private String subject;
private String content;
private String date;
public void setRecipient(String recipient)
{
this.recipient=recipient;
}
public String getRecipient()
{
return this.recipient;
}
public void setSubject(String subject){
this.subject=subject;
}
public void setContent(String content){
this.content=content;
}
public String getSubject(){
return this.subject;
}
public String getContent(){
return this.content;
}
public void setDate(String date)
{
this.date=date;
}
public String getDate()
{
return this.date;
}
public String printDetails()
{
String details="Recipient: "+getRecipient()+
"\nSubject: "+getSubject()+
"\nEmail content: "+getContent()+
"\nDate Sent: "+getDate();
return details;
}
}

Hibernate One-To-Many Mapping, printing mapped lists

I have used One-to-Many Mapping in my project. I have stored a list of clicks for every user.
But when I retrieve the list by calling getClicks() methodm Hibernate returns list in different format.
Something like this.
"[com.zednx.tech.persistence.Click#29df9a77]"
So I tried Reading Every value from the list and assign to a new List.
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
clicks.add(temp);
}
But when i print the items of new List it stills prints the same way.
I need to build a JSON from the resulting String of this list.
So if the list is returned in format, it wont help me.
I couldn't find anything regarding this except How to pretty print Hibernate query results?
I tried Arrays.ToString(Object o). But it doesn't work.
GSON builder part-
Gson gson = new GsonBuilder()
.registerTypeAdapter(Click.class, new MyTypeAdapter<Click>())
.create();
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
temp.setCom_to_recieve(c.getCom_to_recieve());
temp.setStore_name(c.getStore_name());
temp.setT_date(c.getT_date());
temp.setT_status(c.getT_status());
temp.setT_ticket(c.getT_ticket());
temp.setUid(c.getUid());
System.out.println(c.toString());
clicks.add(temp);
}
String json = gson.toJson(clicks, Click.class);
Click.java
#Entity
#Table(name="click")
public class Click {
#Id
#Column(name="t_ticket")
private String t_ticket;
#Column(name="uid",nullable=false)
private long uid;
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
#ManyToOne
#JoinColumn(name="uid",
insertable=false, updatable=false,
nullable=false)
private Earning earning;
#Column(name="store_name")
private String store_name;
#Column(name="t_status")
private String t_status;
#Column(name="aff_source")
private String aff_source;
#Column(name="com_to_recieve")
private float com_to_recieve;
#Column(name="t_date")
private Date t_date;
#Column(name="cb_to_award")
private float cb_to_award;
#Column(name="cb_type")
private String cb_type;
public String getT_ticket() {
return t_ticket;
}
public void setT_ticket(String t_ticket) {
this.t_ticket = t_ticket;
}
public Earning getEarning() {
return earning;
}
public void setEarning(Earning earning) {
this.earning = earning;
}
public String getStore_name() {
return store_name;
}
public void setStore_name(String store_name) {
this.store_name = store_name;
}
public String getT_status() {
return t_status;
}
public void setT_status(String t_status) {
this.t_status = t_status;
}
public String getAff_source() {
return aff_source;
}
public void setAff_source(String aff_source) {
this.aff_source = aff_source;
}
public float getCom_to_recieve() {
return com_to_recieve;
}
public void setCom_to_recieve(float com_to_recieve) {
this.com_to_recieve = com_to_recieve;
}
public Date getT_date() {
return t_date;
}
public void setT_date(Date t_date) {
this.t_date = t_date;
}
public float getCb_to_award() {
return cb_to_award;
}
public void setCb_to_award(float cb_to_award) {
this.cb_to_award = cb_to_award;
}
public String getCb_type() {
return cb_type;
}
public void setCb_type(String cb_type) {
this.cb_type = cb_type;
}
Any Help is appreciated.
You need to implement a toString method, as your current Click class likely doesn't have one, so it just prints as the name of the class and instance identifier.
Okay, I could solve my problem finally.
I made another POJO without any annotations and Mapped the List items to that POJO class.
I think the problem was with Annotation of mapping on another class which I had in original POJO.
Also getString() method only helps in changing format of identifier. So basically it has nothing to do with JSON building unless you format getString() in form of JSON.
Hope it helps. If anyone wants new temp POJO I made I can post it if requested.
Thanks.

java gson fromjson returns null with non-generic type

i've seen that this topic was discussed before, but i havent seen anyone with my characteristics. the title describes what is going on with me. two things, i have go through (i like to think) all the possible answers here, that's why im writing my own question. second thing, the deserialization works perfect in another project and i copied just as it is (maybe that's the problem). i also checked https://sites.google.com/site/gson/gson-user-guide#TOC-Writing-a-Deserializer but i can't find what's wrong with my code. so here is what i have so far:
JSON:
{"offset":0,
"total":137,
"per-page":20,
"events":[
{"id":286560,
"name":"Arsenal vs Everton",
"start":"2015-03-01T14:10:00.000Z",
"status":"open",
"sport-id":15,
"category-id":[158208],
"in-running-flag":true,
"allow-live-betting":true,
"market-ids":[1119280,1121697,1121698,1119271,1119299,1119587,1119288,1118302,1120869,1120870,1121696,1121900,1120868],
"meta-tags":[
{"id":402,
"name":"Live Betting",
"type":"COMPETITION"
},
{"id":19,
"name":"England",
"type":"COUNTRY"
},
{"id":32,
"name":"Premier League",
"type":"COMPETITION"
},
{"id":2285,
"name":"March 1st 2015",
"type":"DATE"
},
{"id":1,
"name":"Sport",
"type":"Root"
},
{"id":4,
"name":"Soccer",
"type":"SPORT"
}]
},
{"id":286960,
"name":"Norwich vs Ipswich Town",
"start":"2015-03-01T14:10:00.000Z",
"status":"open",
"sport-id":15,
"category-id":[158307],
"in-running-flag":true,
"allow-live-betting":true,
"market-ids":[1121701,1121702,1122048,1120062,1120099,1121700,1120050,1120111,1120087,1121620],
"meta-tags":[
{"id":402,
"name":"Live Betting",
"type":"COMPETITION"
},
{"id":33,
"name":"Championship",
"type":"COMPETITION"
},
{"id":19,
"name":"England",
"type":"COUNTRY"
},
{"id":2285,
"name":"March 1st 2015",
"type":"DATE"
},
{"id":1,
"name":"Sport",
"type":"Root"
},
{"id":4,
"name":"Soccer",
"type":"SPORT"}]}
]}
the class:
public class Event {
private String id;
private String name;
private Date start;
private String status;
private String sportId;
private ArrayList<String> categoryId;
private boolean inRunningFlag;
private boolean allowLiveBetting;
private ArrayList<String> marketIds;
private List<MetaTags> metaTags;
public String getId(){
return id;
}
public String getName(){
return name;
}
public Date getStartDate(){
return start;
}
public String getStatus(){
return status;
}
public String getSportId(){
return sportId;
}
public ArrayList<String> getCategoryId(){
return categoryId;
}
public boolean getInRunningFlag(){
return inRunningFlag;
}
public boolean getAllowLiveBetting(){
return allowLiveBetting;
}
public ArrayList<String> getMarketIds(){
return marketIds;
}
public List<MetaTags> getMetaTags(){
return metaTags;
}
public void setId(String id){
this.id = id;
}
public void setName(String name){
this.name = name;
}
public void setStartDate(Date start){
this.start = start;
}
public void setStatus(String status){
this.status = status;
}
public void setSportId(String sportId){
this.sportId = sportId;
}
public void setCategoryId(ArrayList<String> categoryId){
this.categoryId = categoryId;
}
public void setInRunningFlag(boolean inRunningFlag){
this.inRunningFlag = inRunningFlag;
}
public void setAllowLiveBetting(boolean allowLiveBetting){
this.allowLiveBetting = allowLiveBetting;
}
public void setMarketIds(ArrayList<String> marketIds){
this.marketIds = marketIds;
}
public void setMetaTags(List<MetaTags> metaTags){
this.metaTags = metaTags;
}}
and:
public class EventContainer extends Container{
private List<Event> result;
public List<Event> getResult(){
return result;
}
public void setResult(List<Event> result){
this.result = result;
}}
and finally the process to convert from json to the object
public List<Event> listEvents (String sessionToken) throws APIException{
String result = getInstance().makeRequest(MatchBookApiCalls.LISTEVENTS.getApiCallName(), MatchBookApiCalls.LISTEVENTS.getURLSuffix(), sessionToken);
EventContainer container = JsonConverter.convertFromJson(result, EventContainer.class);
if(container.getError() != null)
throw container.getError().getData().getAPIException();
return container.getResult();
}
and the the last:
public class JsonConverter {
/**
* We needed to override the adapter for the Date class so to make all dates to be serialized in ISO8601 UTC
* Just formatting the string to the ISO format does not adjust by the timezone on the Date instance during serialization.
*/
private static final Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new ISO8601DateTypeAdapter()).create();
/** This method deserializes the specified Json into an object of the specified class.
*
*/
public static <T> T convertFromJson(String toConvert, Class<T> clazz){
return gson.fromJson(toConvert, clazz); // this is failing horribly
}
/** This method deserializes the specified Json into an object of the specified Type.
*
*/
public static <T> T convertFromJson(String toConvert, Type typeOfT){
return gson.fromJson(toConvert, typeOfT);
}
/**
* This method serializes the specified object into its equivalent Json representation.
*/
public static String convertToJson(Object toConvert){
return gson.toJson(toConvert);
}}
i've been battling with this for two days, so maybe my brain is a bit burnt and the answer is so stupid i will smash my head on the wall, but i just cant see it. oh! the error is:
Exception in thread "main" java.lang.NullPointerException
at MatchBookApiJsonOperations.listEvents(MatchBookApiJsonOperations.java:46)
at MatchBookPlaceBet.getEvents(MatchBookPlaceBet.java:27)
at MatchBookConnection.testingEntities(MatchBookConnection.java:160)
at MatchBookMain.main(MatchBookMain.java:36)
thanks in advance for any help
the container:
public class Container {
private Error error;
private String json;
public Error getError(){
return error;
}
public String getJson(){
return json;
}
public void setError(Error error){
this.error = error;
}
public void setJson(String json){
this.json = json;
}
}
ok, sorted... my good friend J told me to change the name of the event list to "events" instead of "result" in the EventContainer class (i guess to match the json object "events"), and voila!!!! it works!!! tbh i didn't know it had to match the name, i thought that was something more generic or descriptive, but would never condition whether it parses it correctly or not... well sometimes you have to learn the hard way. Cheers for the rest for the interest and will to help!!

Can update field only once in GAE Datastore using Objectify

I am serializing Diagram class to GAE Datastore using Objectify. I can update (serialize) all the fields as many times as I want, except Integer arrowTypeId, that is only updated once, and after that keeps always the same value. If I leave the app and run it again, I can update again that value, but only once.
To update arroyTypeId I am calling sendDatabaseUpdateDiagramArrows(). This is what happens:
I call sendDatabaseUpdateDiagramArrows() with value 1
I set that value to the DiagramProxy.setArrowTypeId().
As a test, I change the diagram title to DiagramProxy.getArrowTypeId()
I call save()
On the DAO save(), the wrong value of ArrowTypeId is received (keeps the old one), but surprisingly, the Title has the right ArrowTypeId stored from step 3)
Changes are serialized with this problem. No exceptions are displayed.
Note that I am able to update ArrowTypeId value the first time, from default value 1 to 2. Buth the next time keeps always value 2.
Edit: If I change arrowTypeId to a String, I have the same issue.
DatabaseUtils.java
public static DiagramProxy sendDatabaseUpdateDiagramArrows(DialectiveRequestFactory requestFactory, Integer value, DiagramProxy cellDiagramProxy)
{
DiagramRequest diagramRequest = requestFactory.diagramRequest();
DiagramProxy newDiagramProxy = diagramRequest.edit(cellDiagramProxy);
Date date = new Date();
newDiagramProxy.setArrowTypeId(value);
newDiagramProxy.setTitle(Integer.toString(newDiagramProxy.getArrowTypeId()));
diagramRequest.save(newDiagramProxy).fire();
return cellDiagramProxy;
}
Diagram.java
#Entity
public class Diagram extends DatastoreObject{
#Indexed private String diagramId;
private String title;
private Integer arrowTypeId;
public String get_id() {
return diagramId;
}
public void set_id(String diagramId) {
this.diagramId = diagramId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getArrowTypeId() {
return arrowTypeId;
}
public void setArrowTypeId(Integer arrowTypeId) {
this.arrowTypeId = arrowTypeId;
}
}
DiagramProxy.java
#ProxyFor(value = Diagram.class, locator = ObjectifyLocator.class)
public interface DiagramProxy extends EntityProxy{
void set_id(String id);
void setTitle(String title);
void setArrowTypeId(Integer arrowTypeId);
Integer getArrowTypeId();
String get_id();
String getTitle();
}
DiagramDao.java
public class DiagramDao extends ObjectifyDao<Diagram>{
public void save(Diagram diagram)
{
this.put(diagram);
} }
Let me guess :) as I don't have experience with GAE datastore.
I don't get the point, why you make
#Indexed private String diagramId;
but getter and setter with non-standard names:
public String get_id() {
return diagramId;
}
public void set_id(String diagramId) {
this.diagramId = diagramId;
}
I'd rather go for:
#Indexed private String diagramId;
public String getDiagramId() {
return diagramId;
}
public void setDiagramId(String diagramId) {
this.diagramId = diagramId;
}
One more thing is that DiagramRequest code has not been published, maybe that could help in seeing the problem.

Categories

Resources