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

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.

Related

Using a MongoDB Atlas database; how does one set up user accounts, if a user account/password is required to access the DB? (Node, express, mongoose)

Alrighty, so I have a MongoDB Atlas database set up, containing several objects. My current API has several get, post, put and delete end points which are working correctly. However, I am in the process of setting up user accounts and I am a little confused.
My project is built with React on the front end and my server is built with Node, express and mongoose. My goal is that of your typical web application and is as follows:
Go to main web app URL
Home page is a login or "create an account" screen.
Once logged in (or an account is created and you sign into it) you will then have access to get, post, put and potentially delete (if an admin) objects in my DB.
I have built a very basic sign-in, sign-out and "register an account" server which is working however, I am confused as to how to properly go about integrating this with the rest of my API. I currently have the server connecting to my Atlas DB using what is provided in the "connect" menu in the Atlas dashboard (without the < >)
mongodb+srv://<username>:<password>#<cluster-name>.ntwp5.mongodb.net/<collection-name>
Obviously, the username and password (which I can set in my Atlas dashboard) needs to be passed into the "username" and "password" fields in-order to connect to it. I was planning to use the same cluster and have a separate collection for users and my data.
What's confusing me is that in-order to connect to the MongoDB server above and gain access to the two databases, I need to pass in some username/password. However, in order to create an account (ie, creating a new username and password), I would already be utilizing a username and password to connect to the server.
So say I have a group of people in the same company using this application. Would I essentially have a single administrative username/password used by everyone to connect to the server URL? From there, users would be able to access the "users" collection and create an account. Do I then setup my existing API routes (which point to my collection of data) to check that the "signed-in" user exists before returning a successful request and access to that collection?
Or perhaps, the proper way is to use two completely separate databases; one for users and one for my data?
Sorry, I am new to working with Databases and I think the above makes sense to me but I want to verify if that is the correct way to go about handling this. Thanks!

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.

How to merge two cells in the mongodb database?

I'm registering on the site and have already learned how to add cells and remove them using nodejs.Now I need a clue!I need that when a user connects an account such as facebook to an account, his token is tied to the main account. To do this, you need to connect, as in the SQL query of the database, to have a link to the other, so that the user can not bind the account again to another database. How can I arrange this?

After migrating database and mobile service the mobile service is still using old schema

I needed to move an azure project to a new account. My azure project consists of a SQL database and a mobile service connected to that database.
I moved the database by backing up the database into a .bacpac file and importing it in a new Azure account. I recreated the mobile service manually. Because the mobile service needed a different name, I changed the schema on the imported tables by running:
ALTER SCHEMA [NewSchema]
TRANSFER [OldSchema].[TableName]
Now after migration the SELECT works. In the azure portal I can see all the tables have rows, and the mobile service can read from the database. The problem however is in insert, and in Custom API's of the service.
Those seem to still work with the old schema in mind:
Insert: Error: [Microsoft][SQL Server Native Client 10.0][SQL Server]Invalid object name '[OldSchema].[TableName]'. (SqlState: 42S02, Code: 208)
CustomAPI: Error: [Microsoft][SQL Server Native Client 10.0][SQL Server]Invalid object name '[OldSchema].[TableName]'.
There are no references to the old schema that I can find anywhere. Not in the codebase, not in the database.
I even went and executed
SELECT * FROM sys.database_principals
alter user <userName> WITH DEFAULT_SCHEMA = [NewSchema]
for all users.
I am out of ideas. What am I missing, where is it referencing the old schema?
Thank you for your help!
EDIT: I have just tried printing SELECT SCHEMA_NAME() within the Custom API I am trying to execute. It printed the correct, new, schema name. When I printed SELECT CURRENT_USER the correct user is printed, with the correct default schema. I am now more confused than ever.
Can you check your database triggers? There's a trigger that runs on Insert/Update/Delete that may still have a reference to your old schema.

Store Identity UserId in separate table upon first login in Azure Mobile Services

Upon using one of the identity providers (facebook, google etc.) to login for the first time on azure mobile services I would like to store a record of the user's account in a custom user table in order that I could traverse this table using a Scheduled job at intervals. How could I capture the login on the server side to insert/create the Users table.
Just to clarify: I don't want to wait for the user to add a record to a table themselves and then leverage the server side insert procedure of that command. I want to do this initially on first logon.
Is there a way to override the identity login somehow?
Many thanks,
Tomás
You could create a server script:
function insert(item, user, request) {
item.owner = user.userId; //your user
request.execute();
}
for more information about WAMS Server scripts:
http://www.windowsazure.com/en-us/develop/mobile/tutorials/validate-modify-and-augment-data-dotnet/
http://msdn.microsoft.com/en-us/library/windowsazure/jj591477.aspx

Resources