RealmList with Android - android

Items upon inserting
Items upon retrieving
So here is the thing:
I have an Object Product which extends RealmObject.
Inside the Product object, there is an attribute: RealmList. Bundle also extends RealmObject.
Inside the Bundle Object, there is an attribute: RealmList. ProductBundle extends RealmObject.
Now all those lists are not empty nor null by the time they should be inserted.
After insertion, if I query Realm for a list of Products, I will receive a list that has a list of RealmList. However, inside each of the Bundle items, the RealmList< ProductBundle> productBundles is always empty.
class Product extends RealmObject{
RealmList<Bundle> bundles= new RealmList<Bundle>();
boolean isLocallyAddedToCart;
}
class Bundle extends RealmObject{
RealmList<ProductBundle> productsBundles = new RealmList<ProductBundle>();
}
class ProductBundle extends RealmObject{
String title;
}
Any thoughts on that??
Query:
RealmResults<Product> cartItem = realm.where(Product.class).equalTo("isLocallyAddedToCart", true).findAll();
Inserting:
public void insertAddToCart(#NonNull ArrayList<Product> items) {
try {
Realm realm = getRealmInstance();
realm.beginTransaction();
realm.insertOrUpdate(items);
realm.commitTransaction();
realm.close();
} catch (Exception ex) {
ex.getStackTrace();
}
}
Handling the objects:
RealmList<BundleProductOption> bundleProductOptions = new RealmList<>();
private SparseArray<List<ProductBundle>> optionsFinalSelection = new SparseArray<>();
BundleProductOption bundleProduct = new BundleProductOption();
bundleProduct.setDefaultTitle(bundleProductOption.getDefaultTitle());
bundleProduct.setOptionId(bundleProductOption.getOptionId());
bundleProduct.setParentId(bundleProductOption.getParentId());
bundleProduct.setRequired(bundleProductOption.getRequired());
bundleProduct.setType(bundleProductOption.getType());
RealmList<ProductBundle> productBundles = new RealmList<>();
productBundles.addAll(optionsFinalSelection.get(i));
bundleProduct.setProductsBundle(productBundles);
product.setSelectedOptions(bundleProductOptions);

you must manage your insertion with ID as a primary key in each model.
when u insert or update u must use a primary key for saving all states of your data, and then u can do not use them, but realm need them for arrange insert or update method.
keep me updated with your issue .

Related

How could I insert new data to array without key in Firebase

I have an existing array that I created locally and import to Firebase and my array looks like this.
These both elements are objects created that have some many information related to appointments.
Now i am trying to create a new element with the same form, for example:
2--
|__ And the object I have created in my app
I have only managed or eliminate the rest of the elements (with setValue(object))
Appointment newAppointment = new Appointment.Builder()
.fechacita(dateSelected)
.horacita(hourSelected)
.usertoken(mAuthManager.getCurrentUserId())
.oficina(centerSelected)
.build();
mDatabaseRef.child("LISTACITAS").setValue(newAppointment);
or create it with an ID that when recovering the data causes a crash in the application due to the deserialization of the objects that are not equal.
The Appointment object that I want to insert is
public class Appointment implements Parcelable {
private String fechacita;
private String horacita;
private Office oficina;
private String userID;
.....
}
The class is a normal Parcelable class that generates an object with her builder.
Please some help...
try this code
mDatabaseRef.push().setValue(incidentReportUser)
Write it this way (push() adds values instead of overriding).
Ans from here
UPDATE 1
if you want a series in key, not some random value, try this:
get the last key in the list using
Query dbQry = mDatabaseRef.orderByKey().limitToLast(1);
dbQry.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int key = Integer.parseInt(dataSnapshot.getKey());
//Increment the key and add the object here using the earlier method
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
}
I have not checked this as of now, but you could get the idea

Best practice to store object with generic field into a database

I'm implementing an application for private use in Android which request some data from server in JSON format, deselialize it to POJO and need to store objects in a local database. The problem is that Child class contains a generic value, also the value may be primitive type (integer, string, ...) or some custom objects. I tried Realm, but i got NPE. I have read about EAV-Pattern, but I'm not really satisfied with it.
What is the best way to store object containing generic values in a database? I'm not depend on a specific database, but would prefer SQLite.
Simple POJOs of data structure without extends RealmObject:
public class Parent {
public int i;
public Child mChild;
}
A class which contains generic field:
public class Child<T> {
public int i;
public T mValue;
}
A custom object:
public class Value {
public int i;
public String s;
}
An example trying Realm:
Parent p = new Parent();
p.i = 10;
// Child<String> c = new Child<>();
// c.mValue = "I'm a string!";
Child<Value> c = new Child<>();
Value v = new Value();
v.s = "I'm a custom object!";
v.i = 42;
p.mChild = c;
Realm.init(getApplicationContext());
Realm realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
Parent parent = realm.copyToRealm(p);
}
});

Android - Realm relationship list with primary key

ChatRoom:
public class ChatRoom extends RealmObject{
#PrimaryKey
int chatRoomID;
RealmList<ChatMessage> chatMessages;
//getters & setters ...
}
Message class:
public class ChatMessage extends RealmObject {
int chatMessageID;
String chatMessageContent;
User author;
//getters & setters ...
}
User:
public class User extends RealmObject {
#PrimaryKey
int Id;
String Name;
//getters & setters ...
}
Well the first time that the chatmessage is created is fine but in the second time I get an error: Value already exists: 5 [Id of the User]
How can I update the user object when is added to my chatmessage list instead of created a new one?
This is the way that I add a new chatMessage:
mRealm.beginTransaction();
ChatRoom chatRoom = mRealm.where(ChatRoom.class).equalTo("chatRoomID", chatRoomID)
.findFirst();
chatRoom.getChatMessages().add(chatMessage); // add to the list
mRealm.commitTransaction();
It is because of chatMessage is a unmanaged RealmObject and it has the same primary key with one is saved by Realm already.
So if an object is unmanaged object, when added it to a managed RealmList, Realm will try to create it. And an exception will be thrown when an object with the same pk already exists.
To solve this, use copyToRealmOrUpdate() to get a managed RealmObject first then add it, like:
ChatMessage ch = new ChatMessage();
ch.SetChatMessageID(someId);
ch.setChatMessageContent("text");
ch.setChatMessageAuthor(author);
mRealm.beginTransaction();
ch = mRealm.copyToRealmOrUpdate(ch); // get/create a managed RealmObject
ChatRoom chatRoom = mRealm.where(ChatRoom.class).equalTo("chatRoomID", chatRoomID)
.findFirst();
chatRoom.getChatMessages().add(ch); // add to the list
mRealm.commitTransaction();

ParseObject Not saved to Dashboard

I just started to implement parse in my app.
I want to save user data on a cloud so it can be accessed by other users.
I'm trying to subclass the ParseObject just as they guide in their tutorial.
I can see on the dashboard the new class i created, but no object is being uploaded there.
same thing about the exampleObject.
this is the Application Class onCreate():
Parse.enableLocalDatastore(this);
ParseObject.registerSubclass(MyClass.class);
Parse.initialize(this, "XXXX", "YYYY");
ParseObject testObject = new ParseObject("Object");
testObject.put("foo", "bar");
testObject.saveInBackground();
MyClass R = new MyClass();
R.set(...) //here i set all attributes
ArrayList<Ingredient> arrayList = new ArrayList<>();
R.saveInBackground();
MyClass:
#ParseClassName("MyClass")
public class MyClass extends ParseObject implements Serializable , Cloneable{
private attrs; //define Class's attributes
public MyClass()
{
super();
}
I added the uses-permissions and gradle code.
You are using R.set() to set the attributes but there is no set method for ParseObjects and I don't see one in MyClass().
Try using R.put(key, value) to add data to the object.
From Parse.com:
"You can add accessors and mutators for the fields of your ParseObject easily. Declare the getter and setter for the field as you normally would, but implement them in terms of get() and put(). The following example creates a displayName field in the Armor class:"
// Armor.java
#ParseClassName("Armor")
public class Armor extends ParseObject {
public String getDisplayName() {
return getString("displayName");
}
public void setDisplayName(String value) {
put("displayName", value);
}
}

On Android, how can I build a Realm Adapter from a Realm List?

I'm writing a recipe app on Android using Realm. I have a RealmList of type Ingredient in each Recipe object. The object creation code is working fine.
Now I'm writing the code for the Fragment that displays a single recipe. I was able to create a Realm Adapter for the all recipe titles list, since I built that list using a query like so:
public class RecipeTitleAdapter extends RealmBaseAdapter<RecipeTitle> implements ListAdapter {
public RecipeTitleAdapter(Context context, int resId,
RealmResults<RecipeTitle> realmResults,
boolean automaticUpdate) {
...
recipeTitles = RecipeTitle.returnAllRecipeTitles(realm);
final RecipeTitleAdapter adapter = new RecipeTitleAdapter(RecipeParserApplication.appContext, R.id.recipe_list_view, recipeTitles, true);
But now that I'm looking at the ingredients for a single recipe, I have a RealmList of Ingredients and not a RealmResults object. My ingredient adapter class has the same type of constructor as the recipe titles adapter, so I want to know how (or even if) I can make it work starting with a RealmList.
public class IngredientAdapter extends RealmBaseAdapter<Ingredient> implements ListAdapter {
private static class ViewHolder {
TextView quantity;
TextView unitOfMeasure;
TextView ingredientItemName;
TextView processingInstructions;
}
public IngredientAdapter(Context context, int resId,
RealmResults<Ingredient> realmResults,
boolean automaticUpdate) {
....
final IngredientAdapter adapter = new IngredientAdapter(RecipeParserApplication.appContext, R.id.ingredientListView, recipe.getIngredients(), true);
public RealmList<Ingredient> getIngredients() {
return ingredients;
}
Since recipe.getIngredients returns a RealmList, the line where the IngredientAdapter is assigned returns a compile error:
Error:(63, 43) error: constructor IngredientAdapter in class IngredientAdapter cannot be applied to given types;
required: Context,int,RealmResults,boolean
found: Context,int,RealmList,boolean
reason: actual argument RealmList cannot be converted to RealmResults by method invocation conversion
A RealmList behaves like an normal array, so if you cannot make a query that matches what you want to display, you can just use any of the normal adapters like e.g. a ArrayAdapter. The only advantage of using a RealmBaseAdapter is that it autorefreshes, but that is fairly easy to accomplish yourself:
// Pseudo code
ArrayAdapter adapter;
RealmChangeListener listener = new RealmChangeListener() {
public void onChange() {
if (adapter != null) {
adapter.notifyDataSetChanged();
}
}
}
protected void onCreate(Bundle savedInstanceState) {
// ...
realm.addChangeListener(listener);
RealmList data = getRealmListData();
adapter = new ArrayAdapter(data);
listView.setAdapter(adapter);
}

Categories

Resources