Firebase POST to Realtime Database adding an extra section - firebase

I'm trying to upload data into Firebase Realtime Database I have tried first doing a POST through the API this is my Query:
Method: POST
EndPoint: https://[PROJECT_ID].firebaseio.com/users/5Vzshkdlu8W3sDSZMt9bc9SyhiF8.json
Note I'm using my Project ID
Headers: 'Content-Type': 'application/json'
Body:
{
"name": "Rene Alas",
"correo": "[Email]",
"image": "[URL to my Image]",
"title": "Albo Aficionado",
"acceso": 0
}
I tried this on Postman but it gets me an additional part:
As you can see it added a middle part between my given ID and the Data which is Auto Assigned in this particular example:
MTLim4FiFfdeZP4yPZP
Any Ideas how I can put the information underneath the given ID so it doesn't auto assign that key?
Kind Regards?

HTTP semantics say that POST creates a new resource under the location, which is what Firebase does in your situation.
If you want to write a value you specify to the location and overwrite any existing data there, that'd be a call with the PUT method.
If you want the data you pass (on a key by key basis) to be combined with data already at the location, use the PATCH method that Martin mentions.

If you want to update that node, the HTTP request method is PATCH and not POST.
This can be used to update individual childs, see the examples.

Related

GMB - Removal of LocationState object in Business Information API

Google deprecated the old GMB API v4.9 account.locations.get endpoint, and replaced it with Business Information API v1 locations.get.
Code change that affects me is:
Removal of LocationState object. The existing fields have been moved into Metadata.
The new Metadata object does not return the attributes LocationState object contained before. The ones I'm interested in are:
isVerified
isPublished
isSuspended
isDisabled
isDisconnected
etc...
My question is:
How could I get this data without using deprecated endpoints?
Try Verification API getVoiceOfMerchantState
isVerified (verify),
isPublished (hasVoiceOfMerchant=true AND hasBusinessAuthority=true),
isSuspended (complyWithGuidelines),
isDuplicate (resolveOwnershipConflict).
isDisabled & isDisconnected have no equivalent in new API
As far as I can see, based on the link you have sent it is written:
Endpoint URL:
Endpoints for all business information, attributes, categories, chains and locations search are accessible at https://mybusinessbusinessinformation.googleapis.com/v1/ instead of https://mybusiness.googleapis.com/v4/
The path name for locations endpoints has changed from
accounts/accountId/locations/locationId to locations/locationId
Maybe it was better if you could provide the request uri in the previous version so we could help you more precisely. Anyhow, what I tested in the google playground is as follows:
open [https://developers.google.com/oauthplayground]
after setting your clientId and Authorisation stuff, in the Request URI write
https://mybusinessbusinessinformation.googleapis.com/v1/locations/XXXXX?readMask=storeCode,metadata,profile,serviceArea,labels,adWordsLocationExtensions
instead of XXXXX, write your locationId
you can write different readMask fields, The possible fields for readMask are:
play with different fields to check if you have your desired one or not readMask="storeCode,regularHours,name,languageCode,title,phoneNumbers,categories,storefrontAddress,websiteUri,regularHours,specialHours,serviceArea,labels,adWordsLocationExtensions,latlng,openInfo,metadata,profile,relationshipData,moreHours";
If above does not help you, in the link below I see that all metadata attribute of a location might be:
Click [here] (https://developers.google.com/my-business/reference/businessinformation/rest/v1/accounts.locations#Location.Metadata)

Use PUT or PATCH verb when request is updating and deleting: Real life design

I've been trying to get the HTTP verbs right lately, however I have a doubt regarding using PUT, PATCH or even POST for the following scenario.
The front end part is sending the following JSON data:
{
name: "Spanish-01",
code: "ESP01",
students: [{
IdStudent: 1,
name: "Peter Parker"
},
{
IdStudent: 2
name: "Ben Reilly",
dirtyRemove: true
}]
}
The back end code will update the Class record (e.g name and code). However, it will also delete the students with flag dirtyRemove, and those live in another table called Student.
So what's the rule here? Since PUT and PATCH according to w3.org here is for updating an existing resource. In this case the back end is both updating and deleting at the same time?
Should I use PUT or PATCH or neither?
NOTE: Don't mind about the FE part, I minimized the scope in order to get a more straightforward example
How your resources are implemented internally using tables is an implementation detail. It doesn't matter.
That said, your example payload doesn't fit PUT (to remove a student, you would omit it). It might fit PATCH, if you properly label the payload with a content type describing what semantics you expect.
Nit: the HTTP spec is not a W3 document, and the version you're looking at is outdated.

Handling deleted id in Firebase

I'm building an app with a social network component using Firebase, currently if a user likes a post I create a node in the user document called likes and I add the post id, example:
users: {
k9EdVpyRJ2R2: {
likes: {
E36F50C: true
}
}
}
I'm wondering if the post gets deleted should I just handle the deleted post-id on client side when I get the likes ids? or is there a better way to trim the data (or even restructuring it since the app is not live yet)
You'd typically remove the likes at the same time as you remove the post. To efficiently determine what likes to remove, you should keep a link from each post to its likes (in addition to the user-to-likes mapping you already have).
With that you can use a single multi-location update to remove the post and all likes. See this blog post for examples: https://firebase.googleblog.com/2015/10/client-side-fan-out-for-data-consistency_73.html

Key vault values from deployment, and linked templates parameters

I have a template to create a key vault and a secret within it. I also have a service fabric template, that requires 3 things from the key vault: the Vault URI, the certificate URL, and the certificate thumbprint.
If I create the key vault and secret with powershell, it is easy to manually copy these 3 things from the output, and paste them into the parameters of the service fabric template. However, what I am hoping to do, due to the fact that this cert has the same life cycle as the service fabric cluster, is to link from the key vault template to the service fabric template, so when I deploy the key vault and secret (which btw is a key that has been base 64 encoded to a string. I could have this as a secret in yet another key vault...), I can pass the 3 values on as parameters.
So I have two questions.
How do I retrieve the 3 values in the arm template. Powershell outputs them as 'ResourceId' of the key vault, 'Id' of the secret, and 'Version' of the secret. My attempt:
"sourceVaultValue": {
"value": "resourceId('Microsoft.KeyVault/vaults/', parameters('keyVaultName')"
},
"certificateThumbprint": {
"value": "[listKeys(resourceId('secrets', parameters('secretName')), '2015-06-01')"
},
"certificateUrlValue": { "value": "[concat('https://', parameters('keyVaultName'), '.vault.azure.net:443/secrets/', parameters('secretName'), resourceId('secrets', parameters('secretName')))]"
But the certificateUrlValue is incorrect. You can see I tried with and without listKeys, but neither seemed to work... (The thumbprint is within the certUrl itself)
If I were to get the correct values, I would like to try pass them as parameters to the next template. The template in question has quite a few more parameters than the 3 I want to pass however. So is it possible to have a parametersLink element to link to the parameter file, as well as a parameters element for just those 3? Or is there an intended way of doing this?
Cheers
Ok, try this when you get back to the keyboard...
1) for the uri, you can use an output like:
"secretUri": {
"type": "string",
"value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretName'))).secretUri]"
}
For #2, you cannot mix and match the link and some values, it's one or the other.
A couple thoughts on how you could do this (it depends a bit on how you want to structure the rest of your deployment)...
One way to think of this is instead of nesting the SF, deploy them in the same template since they have the same lifecycle
instead of nesting the SF template, nest the KV template and reference the outputs of that deployment in the SF template...
Aside from that I can't think of anything elegant - since you want to pass "dynamic" params to a nested deployment really the only way to do that is to dynamically write the param file behind the link or pass all the params into the deployment resource.
HTH - LMK if it doesn't...
Can't Reference a secret with dynamic id !!!!
The obvious problems with this way of doing things are:
Someone needs to type the cleartext password which means:
it needs to be known to anyone who provisions the environment and how do I feed it into an automated environment deployment? If I store the password in a parameter… ???????
"variables": {
"tenantPassword": {
"reference": {
"keyVault": {
"ID": "[concat(subscription().id,'/resourceGroups/',parameters('keyVaultResourceGroup'),'/providers/Microsoft.KeyVault/vaults/', parameters('VaultName'))]"
},
"secretName": "tenantPassword"
}
}
},

restful-like CRUD operation url pattern for nested model

Generally,the CRUD operation url pattern for model can be like this(Suppose the Model is Post):
new: /posts/new(get)
create:/posts/(post)
edit:/posts/edit(get)
update:/posts/1(put)
get:/posts/1(get)
However if there is a nested model "Comment".
And the association of the "Post" and "Comment" is one-many.
So what should the CURD operation url pattern like for comments ?
new: /posts/1/comments/new or /comments/new
create:?
edit:?
update:?
.......
What is the best practice?
Update:
It seems that the url for comment should be like this:
Get one comment for one post: /posts/1/comments/1
create: /posts/1/comments
update: /posts/1/comments/1
delete: /posts/1/comments/1
Now I am confused with the update and delete operation.
For update and delete: /posts/1/comments/1
SInce the comment id is specified,so I wonder if the /posts/1 inside the url is necessary?
I think the key is whether a comment is "contained" by the post resource. Remember that RESTful urls should be permalinks so under all of your scenarios, the end point to a specific comment(s) must not change. It sounds like it's containted so the url pattern can have the comment nested within the post. If that's not the case (e.g. a comment could move to another post which if nested would change the url) then you want a more flat structure with /comment/{id} urls referenced by the post resource).
The key is if it's a RESTful "Hypermedia API" then like the web it constantly links to the nested or referenced resources. It doesn't rely on the client necessarily understanding the REST pattern or special knowledge as to what end point holds the referenced or contained
resource.
http://blog.steveklabnik.com/posts/2012-02-23-rest-is-over
If a 'comment' is the resource(s) under a 'post' resource:
([httpVerb] /url)
get a post:
[get] /posts/{id}
body has a couple options - either it contains the full deep comments array
(depends on how much data, chat pattern)
{
id:xxx,
title:my post,
comments: [...]
}
... or it just contains the post resource with a url reference to the comments e.g.
{
id: xxx,
title: my post,
commentsUrl: /posts/xxx/comments
}
could also have an option like this (or other options to control depth):
[get] /posts/{id}?deep=true
get a collection of comments within a post:
[get] /posts/{id}/comments
returns 200 and an array of comments in the response body
create a comment for a post:
[post] /posts/{id}/comments
body contains json object to create
returns a 201 created
edit a comment under post:
[patch|post] /posts/{id}/comments/{id}
body contains json object with subset of fields/data to update
returns a 200
replace a post:
[put] /posts/{id}/comment/{id}
body contains json object to *replace*
returns a 200
If you have tons of comments per post, you could also consider a paging pattern:
{
id: xxx,
title: myPost,
pages:6,
commentsUrl:/posts/xxx/comments/page/1
}
then:
/posts/{id}/comments/pages/{pageNo}
{
nextPage: /posts/xxx/comments/2,
pages:7,
comments:
[ { ...,...,}]
}
each page would reference the next page, the page count and an array of comments for that page. If you went with a paging pattern then each comment in the array would have a reference url to the individual comment.
If you find yourself putting an action in the url, you're probably doing something wrong. Good read: http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http
You want to use the canonical URL for delete/update, which would be the complete one. More importantly, you shouldn't be exposing your Primary Key values which come from the Database as ids in the public api that is your restful URL space. These values could change in the future based on a database update, restore from backup, or anything else, depending on vendor. And you don't want an infrastructure change making all your URLs invalid if you can help it.
If you're using /posts/{postnum}/comments/{commentnum}, you can number the public comment ids starting from 1 for every post, making for shorter, nicer URLs.

Resources