Conversations about creating, managing, and using metafields to store and retrieve custom data for apps and themes.
Hello,
I built an embedded app for my company that hit a bump in the road. Our store relies on this app to get everything done due to everything needing metafields. A part of the app attaches new metafields to existing customers, but when I post to
Hi,
Metafields endpoint for the customer resource is not on
https://${store}/admin/customers/${owner_id}.json
It is on
https://${store}/admin/customers/${owner_id}/metafields.json
Let's say with some random metafield request body such as
{ "metafield": { "namespace": "person", "key": "detail", "value_type": "json_string", "value": "{\"middlename\":\"john\"}" } }
As long as your app is using a valid X-Shopify-Access-Token the POST should work fine and I've validated it does on my dev app.
Hope this helps!
But what I am trying to do is add a metafield to and existing customer. I got this code directly from the docs:
Add metafield to an existing customer PUT /admin/customers/#{customer_id}.json { "customer": { "id": 207119551, "metafields": [ { "key": "new", "value": "newvalue", "value_type": "string", "namespace": "global" } ] } }
It actually does work fine using private app credentials but not app credentials
After trying the other way, I'm still getting the same problem. A 401 error.
method: 'post', header: { 'X-Shopify-Access-Token': '*************************************' }, url: 'https://********.myshopify.com/admin/customers/************/metafields.json', data: '{"metafield":{"namespace":"fee","key":"child1_fee1","value":"****************","value_type":"string"}}' },
The example I posted above also adds a metafield to an existing customer and works.
Hmm... okay. Sorry, posted same time. Don't know why you're getting a 401 now. Are you using online access mode and are you sure your access token has not expired?
Ahhh that could be it, I wasn't aware the access token expired. I thought the access token was generated when the app is installed? I have it stored, Is there another way to get a new one?
Edit: I am using offline access mode
I am getting:
{ errors: '[API] Invalid API key or access token (unrecognized login or wrong password)' } } }
Which is weird because before I post I do a get request to get all customer metafields with the same exact access token.
Edit: I'm also doing other calls using the same token and am getting information back, so i'm not sure what the problem is. Maybe scopes? I thought I had approved everything:
APP PERMISSIONS This app can access and modify your store‘s data. Modify store content like articles, blogs, comments, pages, and redirects Modify theme templates and theme assets Modify products, variants, and collections Modify customer details and customer groups Modify orders, transactions, and fulfillments Read all orders Modify draft orders Modify inventory Read locations Modify script tags in your store's theme template files Modify fulfillment services Modify shipping rates, countries, and provinces Read analytics Modify checkouts Modify reports Modify price rules Modify marketing events and related marketing engagement data Modify resource feedbacks Read Shopify Payments balance and payouts
Hi Karl,
I've had a hard time finding information about this newish feature of metafields, and some confusing bits too, as this section of the same documentation (Customer section) seems to suggest a different approach:
Add metafield to an existing customer
PUT /admin/api/2019-04/customers/#{customer_id}.json
{
"customer": {
"id": 207119551,
"metafields": [
{
"key": "new",
"value": "newvalue",
"value_type": "string",
"namespace": "global"
}
]
}
}
I've not been able to get the above to go through, only 406 errors that way.
Using your snippet, I can manually type out an array that is accepted by the Shopify API.
For instance, I'm trying to save a list of emails in a customer metafield and if I paste this as the "value", it goes through:
"[\"guy@buddy.co\", \"friend@friend.co\", \"friend@friend.com\"]"
but if I use javascript code (node v10) to join two lists of emails together (where both vars are arrays)
"value": existing_list.concat(new_invites)
nothing is updated and no error is thrown... So I wonder what to make of that.
If you've any thoughts or notice anything would be much appreciated, I can't find any documentation on working with arrays as the value of a "json_string" metafield type :S
Complete snippet:
let data = await fetch(`${shopifyAPI}/customers/${customerId}/metafields.json`, {
"method": "POST",
"headers": postHeaders,
"body": JSON.stringify({
"metafield": {
"namespace": "referrals",
"key": "invited_emails",
"value": emailsArray,
"value_type": "json_string"
}
})
})
Best
Michel
For anyone trying this too, I am able to update array metafields like so:
let data = await fetch(`${shopifyAPI}/customers/${customerId}/metafields.json`, { "method": "POST", "headers": postHeaders, "body": JSON.stringify({ "metafield": { "namespace": "referrals", "key": toUpdate, "value": JSON.stringify(existing.concat(emails.filter(e => !existing.includes(e)))), "value_type": "json_string" } }) })
Where toUpdate is passed in to the function, existing and emails are both arrays of strings and postHeaders is
const postHeaders = { "Accept": "application/json", "Content-Type": "application/json" }