Sync for the first time the CloudKit data - core-data

My app backup the data to iCloud or sync with user device through the user iCloud account using NSPersistentCloudKitContainer privateDataBase.
The main problem is, when user install the app I need to know if user has data in iCloud or not according this information, I let user to setup account or fetch the existing account, since it takes too long to fetch with local CoreData, I am trying to find a way to fetch directly from iCloud through CloudKit, since I am new in CloudKit, I don't know how to fetch data from CloudKit any help appreciate.

Related

Upload document on iCloud drive using node JS

I am working on an application that allows the user to login into an Apple account and access iCloud drive, I am also allowing the user to upload all documents on iCloud drive. Does Apple provide any open API to upload documents on the iCloud drive? Or Any node package which allows uploading the document on the iCloud drive?
I don't think the iCloud drive API is publicly available for developers right now. But instead of it you can use CloudKit API, it allows you to query on your iCloud data. You can use CloudKit provided CloudKit JS library in your Node application.
Go through this documentation:
https://developer.apple.com/documentation/cloudkitjs

How to enforce immediate Coredata & CloudKit sync?

The setup:
My app uses either private data, i.e. data of a user identified by the iCloud login, or shared data, i.e. data of another user, shared via iCloud.
It uses thus 2 persistent stores, private and shared. Both are mirrored by Coredata & CloudKit synchronization.
When the user switches from private data to shared data and back, fetch requests and save requests are either directed to the private or the shared persistent store.
The use case:
Assume the user is using the private store. In this case, the shared iCloud database and thus the mirrored shared persistent store do not contain any data, since sharing is not activated.
He/she then receives an invitation of another user to share his/her data.
When the current user accepts the invitation, the shared data of the other user are mapped to the shared iCloud database of the current user, and eventually mirrored to the shared persistent store.
The problem:
Unfortunately, mirroring of the shared data does not start immediately. Sometimes, it starts after a few seconds, sometimes only after the app is restarted.
The question:
How can I enforce immediate Coredata & CloudKit mirroring?
Apparently a NSPersistentCloudKitContainer does not have a function to trigger a re-sync manually. One suggestion I found in this post is to re-initialize the NSPersistentCloudKitContainer, which triggers a re-sync.
Is this the right way to proceed?

Azure Cosmos DB - Access different data per user (SQL)

I am new to web development, so the question might be trivial.
I have some physical devices, which will transmit humidity (and other stuff) to Azure Cosmos DB. I want users to be able to read their devices only(through a graph in a web app). All devices end up the the same collection.
I have set up a system in Azure in the following way:
Device -> Azure IoT-Hub -> Azure functions -> Azure Cosmos DB.
The web app uses Azure B2C for users to be able to sign in, but how do i "assign" device-id´s to a user? I have read that it is possible to create access tokens with specific access to certain partition keys, but how do I store the information with access permissions for each user? Do I need a new database for storing this information only?
In the beginning it is fine if I have to grant permissions manually.
General info:
The data in the Azure cosmos db are using device-id as the partition key.
Users can have more than one device.
The web app is running ASP.NET core (I am new here).
The web app requires log-in to be accessed.
I am coding in Visual Studio 2019, and have used the example with a build-in authorization.
Thank you for your help.
NOTE: It might be too much to ask for, but a general explanation together with a code example would be perfect for me :)
UPDATE:
I managed to fetch the email of the logged in user:
#using System.Security.Claims; // for using ClaimsIdentity
// Get user information
var userEmailAddress = ((ClaimsIdentity)User.Identity).FindFirst("emails").Value;
My initial idea is then to have a database containing: "Email" and "accessible devices". I guess this has to be a separate database since i need the Time-To-Live parameter in cosmos db.
You might be able to achieve what you are looking for by using Resource Tokens.
As in this sample from the documentation, you can assign permissions by partition key:
//Create a user.
Database database = benchmark.client.GetDatabase("SalesDatabase");
User user = await database.CreateUserAsync("User 1");
// Create a permission on a container and specific partition key value
Container container = client.GetContainer("SalesDatabase", "OrdersContainer");
user.CreatePermissionAsync(
new PermissionProperties(
id: "permissionUser1Orders",
permissionMode: PermissionMode.All,
container: benchmark.container,
resourcePartitionKey: new PartitionKey("012345")));
Alright, I have been busy with other projects, but i finally came back to this issue.
So basically the reason why I wanted a separate database was because I need the TTL on the Azure Cosmos-DB, and I do not want to delete the user permissions.
It turns out that it is possible to overrule the database's default TTL by setting a "ttl" field in the document itself. Thereby it is possible to exclude documents from being deleted.
So the basic solution is:
Create a documents with a "ttl" parameter set to -1 to exclude it from being deleted. Then this document can contain information about which users have access to what.

Temporary User Accounts: MongoDB vs Redis

I'm developing an application with NodeJS, ExpressJS and MongoDB. Currently I'm working on the user registration process. I would like to store the user account temporary until the user has verified his email address, if the email address is not verified within a certain amount of time, I would like to remove the temporary account.
Currently I've following two ideas to solve the issue:
Creating a mongoose TempUserModel (besides the UserModel), i.e. if the user does the registration a temp user will be created, as soon as the user verified his email address, the temporary user account will be copied to the real Users collection. Some cronjobs could be setup to delete not verified user accounts after a certain amount of time (probably there are better solutions to let expire a mongodb record)
Setup redis to store the temporary user account data, as soon as the email address get verified, a new user will be created in mongodb. With this solution an expire date could be set to remove not verified accounts after a certain amount of time)
Is it better to store a temporary user account in Redis or in MongoDB?
I would recommend storing the temporary user accounts in MongoDB. Storing them in MongoDB has three advantages over Redis:
If you store a temporary user in MongoDB, it will be very easy to convert them to a real user once they have verified. In fact, you could even have the temporary users and verified users share the same schema, with a has_verified field in that schema being the only difference between the two kinds of users. Changing has_verified to true is a lot easier than saving data from Redis to Mongo.
If you are not already planning to create a Redis database for your project, you will only have to maintain MongoDB. Maintaining MongoDB requires less effort and fewer computation resources than maintaining both Redis and MongoDB.
If you ever make changes to your user schema in the future, it would be easier to only make those changes in once place, i.e. MongoDB, rather than to make those changes in two places.

After doing PullAsync() on a table, I am unable to update the table data - Offline data sync in .Net Mobile service

We are developing a windows store 8.1 app, In that we implemented Offline data sync using Azure mobile Service(.net backend).
We are using Mobile service with On-Premise SQL Server with existing database using Code first migrations.
We have a USER table which stores user emailId and offlinePin in the database.
We also implemented AAD single sign on in the app. For all active directory users those who are going to use the app, we added their email ids to the User table with out offlinePin value.
In client app, We are calling the following line based on the user who log in to the app using AAD single sign on.
Declaration:
private IMobileServiceSyncTable<Users> usertable= App.MobileService.GetSyncTable<Users>();
await usertable.PullAsync("SyncLoggedInUserInfo", usertable.Where(user => user.Email == App.UserEmail));
Now for the User who log in based on his/her mail Id we are pulling their information from USER table using above line.
If the logged in user don't have an offline pin then the app will prompt the user to create one and save that into the local SQLite USER table.
For updating the user offlinePin we are calling the following lines
var userInfo = await usertable.Where(x => x.Email == App.UserEmail).ToListAsync();
if (userInfo .FirstOrDefault()!=null)
{
var emp = userInfo .FirstOrDefault();
emp.OfflinePin = pinpswrdbx.Password;
await usertable.UpdateAsync(emp);
}
After updating done we are pushing those changes to the Server.
await App.MobileService.SyncContext.PushAsync();
Here the issue is, the line calling for update the offline pin is not working, means
await usertable.UpdateAsync(emp); is not updating the respective employee information in local table. We are not getting any exception here, it's executing successfully but the offline pin column value is not updating with the user entered pin value.
It is happening only for the rows of data added directly on database and synced to local SQLite DB which are not created within the app, if the record is inserted/created with in the app then that data is updating and am able to push those changes to server as well.
I have to use the existing database and tables which already having data in it and the app should be able to update the data and push the changes back to the server DB.
Can anybody help me where I am missing or doing wrong?
The problem is with the database, it is having case sensitive collation. I used fiddler to track what exactly the mobile service doing while pushing result to server, then I found that in the request URL all the stating letters of the table columns are automatically converting in to capital letters, but in database they are in small letters. May be due to this the data wasn't updated in database and roll backing in local DB as well.
To overcome this issue I had written the below line of code in DBContext class in mobile service project and did publish.
modelBuilder.Entity<User>().Property(p => p.Offlinepin).HasColumnName("offlinepin");
After this updating is working. I don't know why Mobile service did not show any error message when push failed instead it roll back the local values.

Resources