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.
Related
I would like to create an App that has clients and a server (so basically they are 2 different apps). In each of the Clients (and the servers) I use a single-activity-multiple-fragments approach and in each App I have a SQLite database. In some fragments I use a RecyclerView. Now the server should be able to update the recylerview in each individual client (and the database) separately and vice versa, meaning that the clients should be able to trigger an update of the recyclerView and databases of the server.
Now my question is, how can I generally do this in Android? I did an Internet search and often for communication within an app between different fragments the ViewModel and LiveData approach is used. Now I am wondering, if I can also use these approaches for my purposes? I also found an official Android developer page about communcation between Apps https://developer.android.com/training/basics/intents but here they are using intents and I think that they do not use the single-activity-multiple-fragments approach.
So is it possible to use the ViewModel and LiveData approach for that or do I have to use the intent-approach?
Update: I was told that I can't use the ViewModel or LiveData for my purposes. Do you have an idea how I can do what I want? So the clients should be able to send something to the server and the server should be able to send information to the database of the clients and based on that the clients should update their Recyclerview. Can I use sockets for that?
Does nobody have a further idea how I can implement this? As I am struggeling on this question I would highly appreciate your comments and would be quite thankful for your help.
Here you can see a rough sketch of the app architecture.
In fact, the answer to your question does not fit in one text and requires various articles with details. So I just mentioned some links/articles about the implementation of each part. Also, I try to look at the issue from a higher perspective. And then take a closer look at each part.
I separate your problem into two-part:
1. Infrastructure: Communicating data between client and server
According to your comments, these apps are not installed on the same device, but they're in a network and can ping together and the communicated messages are structural data (order of a dish), you have at least 2 options:
If the apps have access to the Internet I suggest using Firebase Realtime Database:
The Firebase Realtime Database is a cloud-hosted database. Data is
stored as JSON and synchronized in realtime to every connected client.
When you build cross-platform apps with our iOS, Android, and
JavaScript SDKs, all of your clients share one Realtime Database
instance and automatically receive updates with the newest data.
also, Google has provided a chat project as codelabs. another example
Using java socket to run the socket server and connect to it. article1 , article2
2. Presentation: reading data and update UI
After implementing send/receive messages, we can use ViewModel and keep messages in a LiveData. And then observe the livedata in fragment/activity and show messages in the RecyclerView.
Google also has provided a couple of codelabs about these subjects too:
Android Kotlin Fundamentals: ViewModel
Use LiveData with ViewModel
Android fundamentals: RecyclerView
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.
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.
I have a question of logic with Firebase. The following is:
I have chat, like WhatsApp, when I open the window of a room I instantiate the Firebase and the window is real-time, for that I am using to implement ArrayAdapter the Firebase to recover and gives push the messages, it is ok for me .
My problem is in recent conversation list, it still is still no real-time connection to the firebase because of this my doubt logic:
1- I create an instance of Firebase for each row of my ListView Adapter that implements this screen? I do not know if Firebase see this as a good practice, moreover, I would have to create an instance of array Firebase.
2 - Today I create my own chat Rooms as taking a part of TimeMillis to maintain the uniqueness of the names of Rooms. From that, I change this to also use ArrayAdpter and let Firebase create the unique Chars for these rooms and have a single instance in the same way it works in the Chat window with open Room? The problem I see in this is that once the local Instance of Firebase will hear all the real-time updates of all the beds, including those not belonging to the user in question. This is easy to be treated by checking the room that Firebase is pushing for the client belongs to it or not, but I think that a security breach, do not you think?
If anyone has any better suggestions, please tell me.
The structure today my firebase console for this project:
{
chats
{
Room1 {},
Room2 {},
...
}
}
Firebase already has an official example of a chat application https://github.com/firebase/firechat
If you follow their database structure you can accomplish this functionality quite easily. You can look at it here.
Basically they have room-messages, room-users and users to keep track of users, rooms, and messages. For more questions about how to strucuture data in firebase, see https://firebase.google.com/docs/database/web/structure-data. With this structure you can listen for updates to an individual room.
Per firebase documentation "it's best to keep your data structure as flat as possible."
I recently started using Kinvey as a backend for my Android app. The documentation doesn't have a lot of info about Collections. I want to know if it's possible to create Collections using the same concepts applied to MySQL tables for example:
A Collection called Users will hold a User ID, Username, User Email
And another Collection called Items corresponding to users -> Item ID, Item Name, User ID.
Has anyone successfully created Collections like this using Kinvey?
kinvey.com
I have also contacted their support team about this bu no reply yet.
I'm an engineer at Kinvey and can help you at this. Kinvey uses a NoSQL store on the back end, so the concepts are a little different than those of a relational database system like MySql, but in general the same thought process can apply. A Collection is similar to a table, although it is Schema-less. This means that attributes (columns in MySql terms) can be added dynamically as needed. You simply create the collection, and then start saving data objects to it. For more info on our Android library specifically, take a look at our Data Store User Guide.