I am making an excersice to understand how Realm is working. The example is having two model classes. One is called User and the other one is called Task. So each user will have a corresponing task.
Here are the two model classes.
public class User extends RealmObject {
#PrimaryKey
private String id;
private String firstName;
private String lastName;
private Task task;
private RealmList<Task> tasks;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Task getTask() {
return task;
}
public void setTask(Task task) {
this.task = task;
}
public RealmList<Task> getTasks() {
return tasks;
}
public void setTasks(RealmList<Task> tasks) {
this.tasks = tasks;
}
}
and
public class Task implements RealmModel, Comparable<Task> {
#PrimaryKey
private String id;
private String title;
private String description;
private boolean isCompleted;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public int compareTo(Task another) {
return 0;
}
public boolean isCompleted() {
return isCompleted;
}
public void setCompleted(boolean completed) {
isCompleted = completed;
}
}
Now in my main fragment I am trying to store those objects in my database.
public class MainFragment extends Fragment {
private static final String TAG = MainFragment.class.getSimpleName();
private Realm realm;
public MainFragment() {
}
public static MainFragment newInstance() {
Bundle args = new Bundle();
MainFragment fragment = new MainFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
// Only create a user if we don't have one.
if (realm.where(User.class).count() == 0) {
User u = realm.createObject(User.class);
u.setFirstName("Theo");
u.setLastName("Tziomakas");
u.setId(UUID.randomUUID().toString());
}
}
});
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
User u = realm.where(User.class).findFirst();
Task t = realm.createObject(Task.class);
t.setTitle("Test Task");
t.setDescription("Foo Bar");
u.getTasks().add(t);
}
});
User u = realm.where(User.class).findFirst();
Log.d(TAG, u.getTask().getTitle());
}
#Override
public void onDestroy() {
super.onDestroy();
realm.close();
}
}
The response I get is:
C:\Users\Theo\AndroidStudioProjects\ReamTutorial2\app\build\generated\source\apt\debug\io\realm\UserRealmProxy.java
Error:(349, 66) error: cannot find symbol variable TaskRealmProxy
Error:(183, 17) error: cannot find symbol variable TaskRealmProxy
Error:(338, 65) error: cannot find symbol variable TaskRealmProxy
Error:(187, 17) error: cannot find symbol variable TaskRealmProxy
Error:(471, 75) error: cannot find symbol variable TaskRealmProxy
Error:(400, 70) error: cannot find symbol variable TaskRealmProxy
Error:(390, 69) error: cannot find symbol variable TaskRealmProxy
I am using the 1.2.0 Realm version.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
classpath "io.realm:realm-gradle-plugin:1.2.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Any ideas what could be wrong?
Thanks,
Theo.
In order for the annotation processor to work on your Realm model classes, you have two options:
1.)
public class Thing extends RealmObject {
2.)
#RealmClass
public class Thing implements RealmModel {
If you look at the source for RealmObject, it starts like this too:
#RealmClass
public abstract class RealmObject implements RealmModel {
Related
I want to develop todo app with the realm database. I have successfully created a list and displayed in recycler view. but when I try to add task inside the recycler view item. I'm a little bit confused. I don't know how to achieve this.
for example:
this is my POJO class
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class ShoppingModel extends RealmObject {
#PrimaryKey
private int id;
private String title;
private String items;
private String color;
private String date;
private String time;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getItems() {
return items;
}
public void setItems(String items) {
this.items = items;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
This is my realm helper class
import android.util.Log;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmList;
import io.realm.RealmResults;
public class RealmHelper {
Realm realm;
public RealmHelper(Realm realm){
this.realm = realm;
}
//save data to realm
public void save(final ShoppingModel shoppingModel){
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
if (realm!=null){
Log.e("Log", "Database was created " );
Number currentID = realm.where(ShoppingModel.class).max("id");
int nextId;
if (currentID == null){
nextId=1;
} else {
nextId = currentID.intValue() + 1;
}
shoppingModel.setId(nextId);
ShoppingModel s = realm.copyToRealm(shoppingModel);
} else {
Log.e("Log", "Database not exits " );
}
}
});
}
public List<ShoppingModel> getAllShoppingList(){
RealmResults<ShoppingModel> shopResult = realm.where(ShoppingModel.class).findAll();
return shopResult;
}
//update data to realm
public void update(final int id, final String title, final String items, final String color, final String date, final String time){
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
ShoppingModel shoppingModel = realm.where(ShoppingModel.class).equalTo("id",id)
.findFirst();
shoppingModel.setTitle(title);
shoppingModel.setItems(items);
shoppingModel.setTime(time);
shoppingModel.setDate(date);
shoppingModel.setColor(color);
}
}, new Realm.Transaction.OnSuccess(){
#Override
public void onSuccess() {
}
}, new Realm.Transaction.OnError(){
#Override
public void onError(Throwable error) {
error.printStackTrace();
}
});
}
// delete from realm
public void delete(final int id, final String title, final String items, final String color, final String date, final String time){
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
ShoppingModel shoppingModel = realm.where(ShoppingModel.class).equalTo("id",id)
.findFirst();
shoppingModel.setTitle(title);
shoppingModel.setItems(items);
shoppingModel.setTime(time);
shoppingModel.setDate(date);
shoppingModel.setColor(color);
shoppingModel.deleteFromRealm();
realm.commitTransaction();
}
}, new Realm.Transaction.OnSuccess(){
#Override
public void onSuccess() {
}
}, new Realm.Transaction.OnError(){
#Override
public void onError(Throwable error) {
error.printStackTrace();
}
});
}
}
Here's my output
Now I want to click that item inside that item i want to add task with checkbox
for example like this
Both List and ShoppingModel cannot be stored in Realm directly. You will need to create a model object for ShoppingModel and then use a RealmList object containing your model objects.
public class ShoppingModel extends RealmObject {
public ShoppingModel() { }
#PrimaryKey
private int id;
private String title;
private String items;
private String color;
private String date;
private String time;
RealmList<ShoppingModelDetails> shoppingListDetails = new RealmList<ShoppingModelDetails>();
// getter setters are here.
}
ShoppingModelDetails class is here -
public class ShoppingModelDetails extends RealmObject {
public ShoppingModelDetails() { }
#PrimaryKey
private int id;
private String title;
private String items;
private String color;
private String date;
private String time;
// getter setters are here.
}
//Add shopping model details objects to shoppingListDetails and store it in your ShoppingList object
You will need to manually convert objects of the ShoppingModelDetails class to the ShoppingModel class when you are inserting/retrieving from the database.
I have 2 applications(different package names) which use one Firebase database. One app has to write access to the database and another have read access to the database.in my second application, i use recyclerview to retrieve data which is stored by 1st App.
for this I use below code:
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId("1:567....259c8f58311") // Required for Analytics.
.setApiKey("AIzaSyA9BRxl......hE03y5qD-c") // Required for Auth.
.setDatabaseUrl("https://mycity-3a561.firebaseio.com/") // Required for RTDB.
.build();
FirebaseApp.initializeApp(this /* Context */, options, "MyCity");
// Retrieve my other app.
FirebaseApp app = FirebaseApp.getInstance("MyCity");
// Get the database for the other app.
FirebaseDatabase secondaryDatabase = FirebaseDatabase.getInstance(app);
DatabaseReference data = secondaryDatabase.getInstance().getReference();
data.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren()) {
for (DataSnapshot dSnapshot : ds.getChildren()) {
WaterClass waterClass = dSnapshot.getValue(WaterClass.class);
Log.d("Show", waterClass.getName() == null ? "" : waterClass.getName());
list.add(waterClass);
}
adapter = new WaterAdapter(ShowWaterDetails.this, list);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
Adapter class
private class WaterAdapter extends RecyclerView.Adapter<WaterAdapter.ViewHolder> {
ShowWaterDetails showDetail;
List<WaterClass> listData;
public WaterAdapter(ShowWaterDetails showWaterDetails, List<WaterClass> list) {
this.showDetail = showWaterDetails;
this.listData = list;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.show_items, parent, false);
WaterAdapter.ViewHolder viewHolder = new WaterAdapter.ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(WaterAdapter.ViewHolder holder, int position) {
WaterClass AllDetails = listData.get(position);
holder.NameTextView.setText(AllDetails.getName());
holder.DetailTextView.setText(AllDetails.getDetail());
holder.DateTextView.setText(AllDetails.getDate());
holder.LocationTextView.setText(AllDetails.getLocation());
holder.TypeTextView.setText(AllDetails.getType());
Picasso.with(showDetail).load(AllDetails.getImgurl()).resize(120, 60).into(holder.ImageTextView);
}
#Override
public int getItemCount() {
return listData.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView NameTextView;
public TextView DetailTextView;
public TextView DateTextView;
public TextView LocationTextView;
public TextView TypeTextView;
public ImageView ImageTextView;
public ViewHolder(View itemView) {
super(itemView);
NameTextView = itemView.findViewById(R.id.ShowNameTextView);
DetailTextView = itemView.findViewById(R.id.ShowDetailTextView);
DateTextView = itemView.findViewById(R.id.ShowDateTextView);
LocationTextView = itemView.findViewById(R.id.ShowLocationTextView);
TypeTextView = itemView.findViewById(R.id.ShowTypeTextView);
ImageTextView = itemView.findViewById(R.id.ShowImageView);
}
}
}
}
POJO Class
class WaterClass {
private String id;
private String email;
private String name;
private String type;
private String detail;
private String location;
private String date;
private String imgurl;
public WaterClass(){
}
public WaterClass(String id, String currentUserString, String imageUrl, String nameString, String typeString, String detailString, String locationString, String dateString) {
this.id = id;
this.email = currentUserString;
this.name =nameString;
this.type = typeString;
this.detail = detailString;
this.location = locationString;
this.date = dateString;
this.imgurl = imageUrl;
}
public String getImgurl() {
return imgurl;
}
public void setImgurl(String imgurl) {
this.imgurl = imgurl;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
:
there is no error but my recycler not showing anything
go to onStart() and start listening
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
and in your onStop
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
The FirebaseRecyclerAdapter uses a snapshot listener to monitor changes to the Firestore query. To begin listening for data, call the startListening() method. You may want to call this in your onStart() method. Make sure you have finished any authentication necessary to read the data before calling startListening() or your query will fail.
Be sure that the names of constant in the POJO match exatly the names
of your database structure in your firebase console !!
ps: do not post your api-keys or app-ids in your questions, keep them secret, and consider using firebaserecycleradapter if you are using firebase-database , it will be more easy to setup and to show values.
Your POJO is ok !
Found Solution!!
just change this part of a code
FirebaseApp.initializeApp(this /* Context */, options, "MyCity");
// Retrieve my other app.
FirebaseApp app = FirebaseApp.getInstance("MyCity");
TO
FirebaseApp.initializeApp(this);
// Retrieve my other app.
FirebaseApp app = FirebaseApp.getInstance("[DEFAULT]");
In the following Realm example,I created two models. One is called Task and the other User. With the help of Realm I am going to use the one-to-one relationship. ie. User "Theo" has one Task.
So here are my models.
#RealmClass
public class Task implements RealmModel {
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#PrimaryKey
private String id;
private String title;
public boolean isCompleted() {
return isCompleted;
}
public void setCompleted(boolean completed) {
isCompleted = completed;
}
private String description;
private boolean isCompleted;
}
And
#RealmClass
public class User implements RealmModel {
#PrimaryKey
private String id;
private String firstName;
private String lastName;
private Task task;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Task getTask() {
return task;
}
public void setTask(Task task) {
this.task = task;
}
}
And in my main fragment I insert dummy data.
public class MainFragment extends Fragment {
private Task task;
private Realm realm;
private TextView textContent;
public MainFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_main, container, false);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
//Create a user if there isn't one
if (realm.where(User.class).count() == 0) {
User user = realm.createObject(User.class);
user.setFirstName("Theo");
user.setLastName("Larsen");
user.setId(UUID.randomUUID().toString());
}
}
});
}
};
handler.postDelayed(r, 1000);
Runnable r1 = new Runnable() {
#Override
public void run() {
final User u = realm.where(User.class).findFirst();
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
//Create a task
Task t = realm.createObject(Task.class);
t.setId(UUID.randomUUID().toString());
t.setTitle("Take out recycling");
t.setDescription("Do it every morning");
//set this task to the user.
u.setTask(t);
}
});
Log.d("TASK","Task title: " + u.getTask().getTitle());
}
};
handler.postDelayed(r1, 1000);
}
#Override
public void onDestroy() {
super.onDestroy();
realm.close();
}
}
However,I get this exception.
io.realm.exceptions.RealmException: 'User' has a primary key, use 'createObject(Class<E>, Object)' instead.
at io.realm.Realm.createObjectInternal(Realm.java:820)
at io.realm.Realm.createObject(Realm.java:801)
at theo.testing.realmapp.MainFragment$1$1.execute(MainFragment.java:58)
at io.realm.Realm.executeTransaction(Realm.java:1253)
at theo.testing.realmapp.MainFragment$1.run(MainFragment.java:52)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I am using that version.
io.realm:realm-gradle-plugin:2.2.1
Any ideas how to fix this exception?
Thanks,
Theo.
Yeah. Do what the exception tells you to do.
Instead of
User user = realm.createObject(User.class);
user.setFirstName("Theo");
user.setLastName("Larsen");
user.setId(UUID.randomUUID().toString());
Do
User user = realm.createObject(User.class, UUID.randomUUID().toString());
user.setFirstName("Theo");
user.setLastName("Larsen");
//user.setId(UUID.randomUUID().toString());
Reason
Primary keys are immutable since Realm 2.0.0, which means you cannot modify them after the object has been created. So pass it at the time of object creation.
Use
User user = realm.createObject(User.class, primaryKeyValue);
add your primary key or generate using UUID.randomUUID().toString()
I am trying to use the google books API with Retrofit, it is returning an empty result.
this is the url:
https://www.googleapis.com/books/v1/volumes?q=9781451648546
In Retrofit I have an interface:
public interface IServiceEndPoint {
#GET("https://www.googleapis.com/books/v1/volumes?q=9781451648546")
Call<BookList> getBooks();
}
in my webservice class I have the following method:
public void getBooks(final Callback<BookList> callback){
IServiceEndPoint endPoint = mRetrofit.create(IServiceEndPoint.class);
Call<BookList> call = endPoint.getBooks();
call.enqueue(callback);
}
in the activity class I have the method:
private void getBooks(){
WebserviceHelper.getmInstance().getBooks(new Callback<BookList>() {
#Override
public void onResponse(Call<BookList> call, Response<BookList> response) {
mBooks = response.body().getResults();
mBookAdapter.update(mBooks);
}
#Override
public void onFailure(Call<BookList> call, Throwable t) {
}
});
}
I have a Java class Book and BookList.
public class Book implements Serializable {
#SerializedName("id")
private String id;
#SerializedName("title")
private String title;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
public class BookList extends Book implements Serializable {
#SerializedName("results")
private List<Book> results;
public List<Book> getResults() {
return results;
}
public void setResults(List<Book> results) {
this.results = results;
}
}
In the manifest file I added
uses-permission android:name="android.permission.INTERNET
mBooks is returning null value, how could I solve this?
Thank you.
EDIT: shuvro's answer helped me correcting the problem. I also forgot to include the volumeInfo in my Book class. My book class looks as followed now:
public class Book implements Serializable {
#SerializedName("id")
private String id;
private VolumeInfo volumeInfo;
public VolumeInfo getVolumeInfo() {
return volumeInfo;
}
public void setVolumeInfo(VolumeInfo volumeInfo) {
this.volumeInfo = volumeInfo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Additionally I created the class volumeInfo:
public class VolumeInfo {
private String title;
private String subtitle;
private String publisher;
private String description;
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Thanks all for the help!
Add the two dependency in your gradle file .
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
Create a class , lets sats ServiceGenerator , your class should be like this
public class ServiceGenerator {
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl("https://www.googleapis.com/books/v1/")
.addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass) {
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}
Now your declare your interface like this
public interface IServiceEndPoint {
#GET("volumes")
Call<BookList> getBooks(#Query("q") String id);
}
Now in activity or in fragment , use retrofit in this way
IServiceEndPoint serviceEndPoint = ServiceGenerator.createService(IServiceEndPoint.class)
Call<BookList> call = serviceEndPoint.getBooks("9781451648546");
call.enqueue(new Callback<BookList>() {
#Override
public void onResponse(Call<BookList> call, Response<BookList> response) {
//do whatever you want to do
}
#Override
public void onFailure(Call<BookList> call, Throwable t) {
}
});
You BookList POJO class has nothing to do with JSON response. It should be something like that:
public class BookList {
#SerializedName("items")
private List<Item> items = new ArrayList<Item>();
}
You can find all POJO classes for that response here.
I would go on this way and simply follow the way to do usually with retrofit.
public interface GBookService {
#GET("volumes?q=9781451648546")
Call<BookList> getBooks();
}
//
public class ApiHelper {
GBookService service;
public ApiHelper(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.googleapis.com/books/v1/")
.build();
service = retrofit.create(GBookService.class);
}
public GBookService getService(){
return service;
}
}
and where you want to use it :
Call<BookList> call = apiHelper.getService().getBooks();
call.enqueue(new Callback<BookList>() {
#Override
public void onResponse(Call<BookList> call, Response<BookList> response) {
}
#Override
public void onFailure(Call<BookList> call, Throwable t) {
}
});
And BookList, you got the idea I guess
public class BookList {
String kind;
int totalItems;
List<Book> items;
...
}
(off course adapt with your own code)
Also be sure to have added the internet permission.
You can follow this because there is no reasons to not success calling the api. just be sure also your field name are correct and match the one contained in the JSON returned.
I recently heard about Realm for android (also available for iOS) in this talk by Joaquim Verques . Very interesting and very powerful tool for persistent data.
I decided to give it a try after the video, researching and reading the documentation.
I found it very easy to use and set up but i end up stuck in the middle of my project because i couldn't manage to successfully make a query with many to many relationships.
I have created a small example for this topic.
My models:
public class Feed extends RealmObject {
#PrimaryKey
private int id;
private String title;
private String description;
private String link;
private Terms terms;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Terms getTerms() {
return terms;
}
public void setTerms(Terms terms) {
this.terms = terms;
}
}
public class Terms extends RealmObject {
private String tag;
private RealmList<Category> categories;
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public RealmList<Category> getCategories() {
return categories;
}
public void setCategories(RealmList<Category> categories) {
this.categories = categories;
}
}
public class Category extends RealmObject {
#PrimaryKey
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
So far so good, now im going to save a list of feeds to realm (make it persistent) and then try to make some query.
public static void test(final Context context,final List<Feed> feedList) {
Realm realm = null;
try {
realm = Realm.getInstance(context);
realm.beginTransaction();
realm.copyToRealmOrUpdate(feedList);
realm.commitTransaction();
RealmResults<Feed> realmResults = realm.where(Feed.class).findAll();// return me all feeds
RealmResults<Feed> realmResults1 = realm.where(Feed.class).equalTo("id", 1).findAll(); // return feed with id 1
RealmResults<Feed> realmResults2 = realm.where(Feed.class).equalTo("terms.tag", "tech").findAll(); // return feeds //with tag = "tech"
RealmResults<Feed> realmResults3 = realm.where(Feed.class).equalTo("terms.category.name", "test").findAll(); //exception here
}
} catch (Exception e) {
//Empty
Log.d("Test","",e);
} finally {
if (realm != null)
realm.close();
}
}
}
Everything run well untill the last query and i get this exception:"java.lang.IllegalArgumentException: Invalid query: category does not refer to a class."
So my question is How do i do that kind of query successfully, as i will like realm to return me every feed with terms which has at least 1 category with name = "test"
Thank you very much
Your field is called "categories" and not "category". The third query should be:
RealmResults<Feed> realmResults3 = realm.where(Feed.class).equalTo("terms.categories.name", "test").findAll();