Getting "One of the specified inputs is invalid" in Azure CosmosDb PatchItemAsync - azure-cosmosdb

Below is the code that I have:
List<PatchOperation> patchOperations = new List<PatchOperation>();
patchOperations.Add(PatchOperation.Replace("/endpointId", 100));
string id = "id1";
PartitionKey partitionKey = new PartitionKey("partitionkey1");
await _container.PatchItemAsync<Watermark>(id,
partitionKey,
patchOperations);
I am expecting to get endpointId property to be replaced with 100.
However, I am faced with Message: {"Errors":["One of the specified inputs is invalid"]}.
May I check which part am I missing or do I have to wait for patch private preview feature to be enabled for my cosmos db?

For anyone else landing here looking for the reason why Cosmos might respond with One of the specified inputs is invalid for other request types, you may need to rename your Id property to id lower-cased or add an attribute:
[JsonProperty("id")]
public string Id { get; set; }

id attribite in cosmos db is case sensitive. Try to replace your id getter setter with "id" this case.

Even though error says "One of the specified inputs is invalid" you should see a status code 400 which indicates Bad Request. So Private Preview feature needs to be enabled for your account.
You can also enable Patch with your emulator by adding EnablePreview when you start the emulator,
.\CosmosDB.Emulator.exe /EnablePreview
In order to get it enabled you can register using this form and it should be done in 15-20 minutes. Let me know if that does not work

Another reason for this error message could be if you forget the forward slash before your property name:
await container.PatchItemAsync<T>(item.Id, new PartitionKey(item.PartitionKey), new[]
{
PatchOperation.Add("isDeleted", true),
PatchOperation.Add("ttl", DefaultTtl),
});
The correct code would be:
await container.PatchItemAsync<T>(item.Id, new PartitionKey(item.PartitionKey), new[]
{
PatchOperation.Add("/isDeleted", true),
PatchOperation.Add("/ttl", DefaultTtl),
});

Related

User-Id for Push-Notification on Actions for Google

I try to make a push notification for my google assistant app.
I used the sendNotification Code form the google developer site: https://developers.google.com/actions/assistant/updates/notifications
I am coding Java.
Everything is working, expect getting the correct user id.
When I hardcode my user it works, but how do I get the user id in the code?
I tried following code:
Argument arg_userId = request.getArgument(ConstantsKt.ARG_UPDATES_USER_ID);
String userId = request.getUser().getUserId();
--> I get "java.lang.reflect.InvocationTargetException"
String userId = arg_userId.getRawText();
--> same Exception
There are two problems with the approach you're taking to get the notification ID:
The ID attached to the user object is deprecated and probably unavailable.
This wasn't the ID you wanted anyway.
In the response where the user finalizes the notification, that response includes an ID which you should get and store. Since you're using Java, the code might look something like this:
ResponseBuilder responseBuilder = getResponseBuilder(request);
Argument permission = request.getArgument(ConstantsKt.ARG_PERMISSION);
if (permission != null) {
Argument userId = request.getArgument(ConstantsKt.ARG_UPDATES_USER_ID);
// code to save intent and userID in your db
responseBuilder.add("Ok, I'll start alerting you.").endConversation();
} else {
responseBuilder.add("Ok, I won't alert you.");
}
return responseBuilder.build();

How to get Google UserId from active user session in App Maker?

Is there a way to get "User Google Id" from the session in App Maker. In the documentation its only mentioned how to retrieve the email of the logged in user Session.getActiveUser().getEmail() but no where it says how to get the id. I need this because the user email might sometimes changes. So I need the user id to keep track of users and related permission tasks. Or is there something I'm missing out here in how this should be implemented.
Yet an easier way to find Google Id simply using the Directory model. Although its mentioned in documentation that there is a way to get current signed in user id ( which is Google Id), its not clearly stated how - maybe documentation could be improved here. Another problem is that in many occasions the email of current active user is referred to as the id for example in deprecated method Session.getActiveUser().getUserLoginId(). Anyways this is a proper way to get the id.
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
var result = query.run();
var GoogleId = result[0]._key;
So with this GoogleId you can safely relate different models with each other and not worry that database integrity might break if an already referenced user email is changed.
Relating the different models could be done simply by creating a model that acts as a wrapper model around the Directory model and storing GoogleId in it. Then linking that model to other models where you want to track user related data because unfortunately we can not directly link The Directory Model to other models.
A team member has figured it out. This should be done using Apps Script - which works within App Maker environment using server side script.
var GoogleUser = (function (){
/**
*
* #param {string} email
*/
function getUserObjByEmail(email){
// Same as using AdminDirectory class.
var apiUrl = "https://www.googleapis.com/admin/directory/v1/users/"+email+"?fields=id";
var token = ScriptApp.getOAuthToken();
var header = {"Authorization":"Bearer " + token};
var options = {
"method": "GET",
"headers": header
};
var response = JSON.parse(UrlFetchApp.fetch(apiUrl, options));
return response;
}
/**
*
* #param {string} email - User email.
*/
function getIdByEmail(email){
return getUserObjByEmail(email)['id'];
}
var publicApi = {
getIdByEmail: getIdByEmail
};
return publicApi;
})();
Note that using var apiUrl = "https://www.googleapis.com/admin/directory/v1/users/"+email+"?fields=id"; is not going to be asynchronously called because its already happening in the server.
Is this a dup of this question?
I think this will solve your problem, even though it's a bit of a hack.

How to allow Flutter to get a value that it stored in a firebase server or any server?

Right now I am using an http 0.11.3+16 and I am able to add a true value to an item on the site using the following function:
if (newAcceptStatus) {
response = await http.put('https://example.com/example1/${selectedOrder.id}/example2/${_authenticatedUser.id}.json?auth=${_authenticatedUser.token}',
body: json.encode(true));
this function is only called when the admin is logged in and the admin is the only one that can change the status of the Boolean, so the value is stored under the admins id and token. so I tried the following to help show if the item was changed by the admin to the user but i keep getting that the value is null when i decode the response with the following function:
Future<Null> checkAccept() async{
http.Response response;
response = await http.get('https://example.com/example1/${selectedOrder.id}/example2/(admin id goes here).json?auth=${_authenticatedUser.token}');
accepted = json.decode(response.body);
}
not sure what i am doing wrong. any help would be appreciated!
I was calling the wrong list of items which were very similar, thus giving me an empty list

Cannot update a timestamp column after .Attach

I have this ASP.Net code and I was getting an error when running it. The error was:
Server: Msg 272, Level 16, State 1, Line 1 Cannot update a timestamp
column.
Here's the mapping for this table that I already have:
Property(x =>
x.Version).HasColumnName(#"Version").IsOptional().HasColumnType("timestamp").HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed);
Note that I do have a version column in my table.
public async Task<IHttpActionResult> Put([FromBody]WordForm wordForm)
{
// SampleSentences -> s
var oldsObj = db.SampleSentences
.Where(w => w.WordFormId == wordForm.WordFormId)
.AsNoTracking()
.ToList();
var newsObj = wordForm.SampleSentences.ToList();
// There is other code here to modify SampleSentences
//
//
// db.WordForms.Attach(wordForm);
// db.Entry(wordForm).State = EntityState.Modified;
wordForm.StatusId = (int)EStatus.Saved;
await db.SaveChangesAsync(User, DateTime.UtcNow);
return Ok(wordForm);
}
I was able to fix the error by adding comments to the two lines in the method. But could someone explain why I am getting the error if I don't comment out those lines. Should I not be able to Attach the wordForm and mark as Modified?
Your table probably has a rowversion or timestamp field which is used for optimistic concurrency. rowversion fields can't be set or updated at all. They are a value that gets incremented automatically each time a row is modified.
To avoid the problem, mark your rowversion property with the TimeStamp attribute:
[TimeStamp]
public byte[] RowVersion { get; set; }
In fact, timestamp is the deprecated name of the type which causes a bit of confusion
From the docs:
The timestamp syntax is deprecated. This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

GitKit Client - Uploaded users cannot connect

We have an existing user database with SHA1-encoded passwords. We upload them to the Google Federated Database (through the GitKitClient java lib), but then these uploaded users can't log in The verifyPassword always returns "Incorrect password" ! The call to the uploadUsers looks like gitkitClient.uploadUsers('SHA1', new byte[0], gitkitUsers)
(We must provide an empty byte array as second param (hash key), since we get NPEs if we provide a null value)
The method that creates the GitkitUsers that are in the list is as follows:
private GitkitUser createGitkitUserFromUser(User user) {
GitkitUser gitkitUser = new GitkitUser()
gitkitUser.email = user.email
gitkitUser.localId = getLocalId(user)
gitkitUser.name = user.displayName
gitkitUser.hash = user.password?.bytes
if (user.pictureFileName) {
gitkitUser.photoUrl = user.getPictureUrl()
}
return gitkitUser
}
We see no way to further investigate. Did someone successfully use it ?
Make sure that the hashKey you use in setPassword() is the same one used in uploadUsers().
I am using the php SDK so I can't share code for you, but when I did NOT use the same hashKey for both places, I had the same problem.

Resources