I'm currently working on a Tinder-like app, where users get recommandations of other users, that are chosen by some algorithm. Each user will have it's own user specific realm, but this data will also be shared as the other users get this user as a recommandation. From what I have read, the shared realm will automatically get duplicated on the local devices of each user, which I definitely don't want.
So how can I now have a pool of users, but only share the calculated users by my algorithm to each user separately?
I have read some other threads about this topic also had a look into 'Designing a Database: Realm Threading Deep Dive', but at the moment I have no idea how to design my realm environment. Thanks
At the moment, the recommendation is to split the data into separate Realm files and move it between Realm files on the server in your own code.
We realize this is a bit cumbersome, and are currently working on better ways to achieve fine-grained sharing of data between users with object-level permissions. Stay tuned in the coming weeks and months.
Until then, duplicating the data into user-specific Realms is the best way forward.
Related
So for the past few days I have been reading through the Realm documentation and I am very excited to use this data synchronization solution in upcoming projects. After using standard database schemas (SQL, Firebase, etc). I am still not fully understanding the best way to utilize Realms. I see Realms are meant to be very flexible, but there are not many examples or docs of how to set up and efficient structure.
So, I wanted to just provide a simple collaborative app idea, and show my first thoughts on how I would set up the Realms. For simplicity, lets say this is a messaging app that contains chatrooms. Users can create chat rooms and the owner of the room can invite people to their room. Once that user is added to a room, they will have read/write access to the room.
My current structure:
1) A realm for each user. (/Users/uid) . Each one of these realms will have public read access and write access only for the user that owns it.
2) A realm for each chatroom. (ChatRooms/uid) . Each chat room will hold the various models pertaining to that specific room (messages, likes, notifications, etc). Initially only the owner will have read/write access, everyone else will have no access. The owner can then start handing out read/write permissions to the users they invite.
3) A public realm that holds mappings of a user to a chatroom. (ChatMembers). This realm will hold models that have two attributes, a user id and a chatroom id. A user can query this realm by there id to see what chatroom realms they will have access to.
I feel this is a very basic structure, but I am still not positive if this is utilizing Realm to the best of its abilities. Also, if anyone can lead me to some better documentation, please do. Would appreciate anyones feedback!!
Refer to: https://docs.realm.io/platform/getting-started-1/android-quick-start/step-4-chat-room-permission-api
Here they have used the permission API and partial sync,to design a chat app that enables the user to create public and private chat rooms.
I would also recommend you to follow the previous steps also mentioned in the above link, to have a basic understanding of how realm works.
I have a question about users accessing data created by another user. I will explain below with a case study.
I am using Realm Mobile Platform. The app uses Realm Auth to allow users to register by email, google and facebook account. At this moment I am using as a REALM_URL: ...":9080/~/name".
I will try to explain what I would like to achieve with the following example.
Imaging that I have UserA and UserB. Once the users have registered in the app (using SyncUser), they would be redirected to a project activity. Each user would be able to create their own projects. Before Realm Mobile Platform (Realm Mobile Database), user data was stored in user devices. Now, because I am using "~" in the REALM_URL, when users entered in the project activity, the activity requests and shows all the existing projects for that user.
The app has another activity with a search functionality where users can search for public projects. For example, the UserA makes public Project1. UserB should be able to find Project1 and follow it, or ask the owner to become a contributor. Once the UserB follow or get access as a contributor, Project1 should be shown in the Project activity of UserB.
The question is how to make this possible.
Option A: Use a unique and common Realm for all users.
Deleting the "~" from the REALM_URL and adding different fields like "ownerID" to the project RealmObject and a list of subscribed projects to the user RealmObject. This will allow user to query to all the projects (owned and subscribed) in the project activity and search for public projects in the search activity.
Option B: Use two realms, one private for the user data, and one public for projects.
The private would have a REALM_URL including the "~" and the public will be absolute. Later, when a new user sign up the app would give privilege (mayRead, mayWrite, mayManage) through the Access Control.
Which one would be a better option? Is there any other better option?
Thanks
The answer to your question is, it depends. The Realm Mobile Platform (RMP) will automatically handle all of your data sharing, conflict resolution, and syncing across the users. In this way, RMP acts as a server and single source of truth.
Both OptionA and OptionB will require this single source of truth and some knowledge of user access control.
Let's go through the pros and cons of each option.
OptionA:
Pros
Only one database, conflict resolution is done by Realm
Significantly less work on the mobile side, you just listen to
the server
Cons
Potentially difficult to do user access control
OptionB:
Pros
User's private data is completely separate
Cons
You will be responsible for writing the data conflict resolution between the local database and the server
Your app will most likely be larger due to storing multiple databases.
In my experience, dealing with database conflict-resolution yourself is truly painful. It seems like OptionA is by far your better option.
My Android app is fetching data from the web (node.js server).
The user create a list of items (usually 20-30 but it can be up to 60+). For each item I query the server to get information for this item. Once this info is fetched (per item), it won't change anymore but new records will be added as time go by (another server call not related to the previous one).
My question is about either storing this info locally (sqlite?) or fetching this info from the server every time the user asks for it (I remind you the amount of calls).
What should be my guidelines whether to store it locally or not other than "speed"?
You should read about the "offline first" principles.
To summarize, mobile users won't always have a stable internet connection (even no connection at all) and the use of your application should not be dependant on a fulltime internet access.
You should decide which data is elligible for offline storage.
It will mainly depend on what the user is supposed to access most often.
If your Items don't vary, you should persist them locally to act as a cache. Despite the fact that the data mayn't be really big, users will welcome it, as your app will need less Internet usage, which may lead to long waits, timeouts, etc.
You could make use of Retrofit to make the calls to the web service.
When it comes to persisting data locally within an Android application, you can store it in several ways.
First one, the easiest, is to use Shared Preferences. I wouldn't suggest you this time, as you're using some objects.
The second one is to use a raw SQLite database.
However, I'd avoid making SQL queries and give a try to ORM frameworks. In Android, you can find several, such as GreenDAO, ORMLite, and so on. This is the choice you should take. And believe me, initially you might find ORMs quite difficult to understand but, when you learn how do they work and the benefits they provide us, you'll love them.
first of all, Im new in developing android.
For creating my next android app (native eLearning client for learning different scripting languages), I've got some questions about the best practise in case of databases. My goal is it, to create an android client which depends on this stack: nodejs+express+MySQL for the user handling (User handling shouldn't be schemaless) and MongoDB for the data management (Which should be schemaless, because it could vary in some future) and for example Cassandra for User activity Logs.
A User could be in many (private) groups, and a group can have many user (n:m), should i realise it over MySQL or should I only depends User into MySQL and Groups into NoSQL? The User will make a huge number of posts, so the posts should be saved in a NoSQL beacuse the performance (read,write). I would prefer first, best practise???
I read for the User login handling many about "shared prefences with encryption" and "redisDB for user session".It should have the option for a permanent login. Which one is the common or best practise way(performance, handling...) to realise for an android client?
Im glad for any suggestions.
initially if you dont have heavy user base then go with mysql. as it's very simple as well as mature database flavor. You should have to use mongo nad redis only when you have performance bottle neck rather than initial database. I am suggesting this as to use the NOSQL use should have better understanding. So, go for the MySQL and use NOSQL only when it requires.
My app will pull some json data when it is started and realistically, once the data has been pulled, I really won't need to pull it again for the duration of the user experience. The backend data may update a few times a day at most, so I think I would like to just grab the data upon app start and then use that same data for the duration and give the user an option to manually refresh the data. So, my question is, where/how should I store that data? I've got all of my data structures set up (classes and sub-classes). And there may be 200 or so instances of some of the classes. If I store everything as member variables in my activity_main class, it won't be available to other activities once the other activities are started. Storing them all in databases could be an option, but it sort of feels like overkill. I really don't need the data to persist between sessions. Is there a way to easily store it in memory and still have it easily accessible to all activities?
You should think about OS killing your app process on low-memory, so backing your data on disk is a good thing to do. Doing so you have an ability to show user data from disk cache while refreshing it in background from server.
Choosing the tool for data storage depends on the way you need to work with data.
Of course, there is an option to use Realm, but you should consider the fact that it is not the relational database. So if you have complex domain model with joins and other relational stuff for your business logic, I'd go with something other. It is thread-safe, also has migrations (but, as for me, migrarations are always pain, you just can not do anythig about it). Realm is supposed to be RxJava-friendly now (support added in v0.87) There are some disadvantages(part of them may already be fixed), but you should consider it before using.
As for more relational approach, there is SQLBrite library:
A lightweight wrapper around SQLiteOpenHelper which introduces reactive stream semantics to SQL operations.
It is not an ORM (but you can add some kind of it on top of SQLBrite if you wish: see this for more info). In fact, being alone this library is doing one thing (and doing it good) - it provides a mechanism for coordinating and composing the notification of updates to tables(Realm also has such ability) such that you can update queries(in SQL fashion) as soon as data changes. And it respects RxJava!
As an alternative to SQLBrite you can look at StorIO.
There are also lots of different ORM solutions, like GreenDAO, ORMLite etc.
But I'm pretty sure, one of the first two libraries (Realm or SQLBrite) will likely help you. So analyze your app, these libs and decide what fits better.
P.S. Great article on how RxJava would help you to work with data from different data sources (in-memory cache + disk cache + network) easily. Might be helpful!
I would still recommend a SQLite Databse, you can easily declare it as a 'in-memory' database, if that is what you want.
However.... I would be rather upset as a user of your application if it downloaded redundant data over and over. I would just recommend making a content provider and being done with it. This gives you access to a SyncAdapter, and defines clear boundaries between where code should go.
The 'trick' with making a good ContentProvider is to make good POJOs, that have methods to convert from POJO -> ContentValues and Cursor -> POJO(s).
Easiest thing is to do is store the json file in Apps data storage and parse the json every time you need.
But this is not recommended as it is costly to parse data every time.
Best option is to implement Realm (Replacement for Sqlite) which is very easy to implement and its amazingly fast.