Retrieving ArrayList of Custom objects in firebase - java

How would you go about storing and retrieving an ArrayList of custom objects in firebase? In my android application, I store and retrieve an array as follows
Storage:
ArrayList<GameQRCode> qrCodes = new ArrayList<>();
qrCodes.add(new GameQRCode("name1", "value1"));
qrCodes.add(new GameQRCode("name2", "value2"));
qrCodes.add(new GameQRCode("name3", "value3"));
User user = new User("myUsername");
user.setQrCodes(qrCodes);
db.collection("users").document("myUsername").set(user);
Retrieval:
db.collection("users").document("myUsername").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
ArrayList<GameQRCode> testList = (ArrayList<GameQRCode>) task.getResult().get("qrCodes");
}
});
However, when I try to use the retreived ArrayList, I get an error message like follows...
GameQRCode qrCode = qrCodes.get(position);
java.util.HashMap cannot be cast to com.example.qracutie.GameQRCode
Your help is greatly appreciated

Firestore doesn't remember the type of custom object you used to in your collection generic type, so you can't simply cast it the way you put it in after you get the document back. The error message is telling you that it stored data as a Map instead of your custom object type. It will be your responsibility to deal with that Map directly, pulling values out of it and mapping them back into your custom object. This means that you should probably pull data out like this:
List<Map<String, Object> testList =
(List<Map<String, Object>>) task.getResult().get("qrCodes");
In fact, you should be aware that Firestore will internally map everything to one of these basic types: Map, List, String, Integer/Long, Boolean, null. You should expect to get only these types, and you should probably also check the types of instanceof before you cast anything at all, in order to make sure that you never make an incorrect cast at runtime.

Related

Firebase onMessageReceived() returns no getNotification

Calling remoteMessage.getNotification() returns null and
when calling remoteMessage.getData() I get a strange object back that has an initial property _wp={ as listed below. I need to extract the alert property each time but I am not sure how.
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
RemoteMessage.Notification notification = remoteMessage.getNotification();
Map<String, String> data = remoteMessage.getData();
Log.d("DATA", remoteMessage.getData().toString());
sendNotification(data);
}
The remote data log returns the below. So I can't seem get the title and text I need to in order to construct my notification.
{_wp={"c":"01euntvtna3epk83","alert":{"text":"Body text","title":"test"},"receipt":false,"type":"simple","targetUrl":"wonderpush:\/\/notificationOpen\/default","n":"01eunu08bjla8303","reporting":{"campaignId":"01euntvtna3epk83","notificationId":"01eunu08bjla8303"},"receiptUsingMeasurements":true}, alert=Body text}
I basically want to use them with when using the NotificationCompat.Builder
.setContentTitle(title)
.setContentText(text)
Any help will be greatly appreciated.
It is normal that remoteMessage.getNotification() returns null as WonderPush only uses FCM notifications with data inside them, nothing in the Firebase's own format.
remoteMessage.getData() returns you with a map that can only store String values. This corresponds to the top-level JSON payload. This map's fields are the top-level JSON object fields, and its values are all stringified.
So you'll have to parse the _wp key using new JSONObject(remoteMessage.getData().get("_wp")).
You'll basically read the title and text fields of this parsed _wp JSON object to feed .setContentTitle() and .setContentText() of the NotificationCompat.Builder.
But you should note that the WonderPush Android SDK is precisely here for that purpose:
Here is the code that parses the notification's _wp.alert field: https://github.com/wonderpush/wonderpush-android-sdk/blob/v4.0.2/sdk/src/main/java/com/wonderpush/sdk/AlertModel.java
Here is the code that builds the notification: https://github.com/wonderpush/wonderpush-android-sdk/blob/v4.0.2/sdk/src/main/java/com/wonderpush/sdk/NotificationManager.java#L448-L775
If you have an addition, it would make more sense to fork, hack, submit a pull request, and use your fork in the meanwhile.
Best,

Does Using SnapshotParser while querying firestore an expensive operation?

Does using SnapshotParser while querying Firestore an expensive operation in terms of read operation?
We are building query in our app like this:
options = new FirestoreRecyclerOptions.Builder<Item>()
.setQuery(query, new SnapshotParser<Item>() {
#NonNull
#Override
public Item parseSnapshot(#NonNull DocumentSnapshot snapshot) {
Item item = snapshot.toObject(Item.class);
item.setId(snapshot.getId());
return item;
}
})
.setLifecycleOwner(this)
So while reading data from server, does SnapshotParser will make extra read operation (or hit server again) or it will parse using already read data?
Would it be the same operation(in terms of server hit) with or without SnapshotParser?
Please explain, if anything is missed, please let me know? Sorry for bad english.
From the official documentation of Firebsase-UI library:
If you need to customize how your model class is parsed, you can use a custom SnapshotParser.
So if you need to customize your model class it doesn't mean that you are creating extra read operations. The parseSnapshot() method uses as an argument a DocumentSnapshot object which contains the data set that you are getting from the database for which you are already charged in terms of read operations. This is happening if the the query return data. If your query does not return any data, you are still charged but only with a single read operation.

Android Firebase and Converting Hashmap back to Object

I'm pulling out information into a series of classes using the Firebase SDK in Android. My classes do indeed contain my data, but on trying to extract my data of something as the same class, I get:
java.lang.ClassCastException: java.util.HashMap cannot be cast to CustomItem
I have a class, called CustomItems, that has:
public Map<String, CustomItem> Items;
I'm loading this, by setting the following in the onDataChange event.
Items = (HashMap<String, CustomItem>) dataSnapshot.getValue();
Anyhow, on trying to read this information by using CustomItem item = Items.get('key'), shows me the correct object name of CustomItem in Android Studio and it's Intellisense, however always returns a Hashmap.
Having written this so far, Im wondering if I now need to actually iterate through the children to set a new CustomItem as
item = child.getValue(CustomItem.class);
And then add that item to a List in CustomItems.

JavaFX: Create custom data attributes for nodes

I am currently in need of custom attributes which I can fetch anytime. Is there any way to create custom data attributes for nodes and then get those values in javafx?
Lets assume I have the the follwing Button.
<Button text="Im a button" fooBar="I hold some value" />
Similar to: https://developer.mozilla.org/de/docs/Web/Guide/HTML/Using_data_attributes
Now in HTML I could simply do the following:
<div id="example" data-foobar="I hold some value"></div>
Then I could easily get the data like this:
document.getElementById("example").dataset.foobar;
Edit: I need more than 1 data property for a node because a node can hold various information.
The data can be stored in the properties ObservableMap of a Node
Node node = ...
node.getProperties().put("foo", "bar");
...
Object foo = node.getProperties().get("foo");
Note however that some layout properties use this map too, so no property names similar to javafx properties / "static" properties should be used as key. To be sure you could create a custom key class that does not return true if an object of another type is passed as parameter to equals.
To solve your problem you should to use userData it can be any object that you need.
node.setUserData("Hello world");
node2.setUserData(123);
etc.
If you need to set multiple values you can save your values in an array, list, json etc.
ArrayList<String> vals = new ArrayList();
vals.add("Hello");
vals.add("World");
node3.setUserData(vals);
//some code
ArrayList<String> result = (ArrayList) node3.getUserData();

How do you send checkbox data in Jsoup

I am trying to post checkbox data with Jsoup and am having a little trouble. I thought that when multiple checkboxes are selected, they are sent as an array to the server but maybe that is not the case?
This is what I thought was correct:
HashMap<String, String> postData = new HashMap<String, String>();
postData.put("checkbox", "[box1,box2,box3]");
Jsoup.connect("somesite").data(postData).post();
This does not seem to work properly. However, if I send only a single checkbox then I get my expected results leading me to believe my understanding of how checkbox form data sends is incorrect.
This works:
postData.put("checkbox", "box2");
Maybe HashMap is the wrong type to use. According to the Jsoup documentation I could just call .data(key, value) multiple times but I was hoping for something a little cleaner than that.
If you have multiple checkboxes, then presumably each checkbox has its own name attribute. You should then call .data(name, value) for each such name.
AFAIK there's no way to "collapse" these calls to data into a single call.
Maybe You can try something like the following ?
HashMap<String,String> paramHM=new HashMap<String,String>();
ArrayList<String> checkboxVal=new ArrayList<Strnig>();
/ .. put request.getParametersValues() in this arraylist
org.jsoup.Connection jsoupConn=Jsoup.connect(web_api).data(paramHM);
// Multiple Call that
for(String item:checkboxVal){
jsoupConn=jsoupConn.data("checkbox",item);
}

Categories