Javascript Buy SDK - Error: Not Found - javascript

I'm trying to retrieve products from my Shopify store with this code, a near copy/paste of the examples page for the Javascript Buy SDK:
$(function() {
var shopClient = ShopifyBuy.buildClient({
accessToken: '4b4e3d4bba63039f2d51db94c2e79a46',
domain: 'squatch-air-clutches-test.myshopify.com',
appId: '6'
});
shopClient.fetchQueryProducts({
collection_id: 1397227547
}).then(function(products) {
$('.test').append(JSON.stringify(products));
});
shopClient.fetchProduct('46656520219').then(function(product) {
$('.test').append(JSON.stringify(product));
});
});
Here's a fiddle.
The buildClient command seems to complete successfully, however I get a console error with the next two commands: Error: Not Found. I assume this refers to the product not able to be found, but I am sure both the product and the collection ids are correct. And I am also sure that I have read access enabled for "products, variants, and collections" for my private app. Would there be any other reason I am getting this error, and if so, what's a solution?

Got it. The App ID was incorrect. I needed to go to /admin/settings/storefront_access_tokens and grab the correct ID for my sales channel. I'm disappointed that it was so difficult to find though - the documentation on this seems convoluted.

Related

Error with AWS SDK-JS API when Retrieving Seller Partner Product Catalog Inventory

I need to retrieve the product catalog of my seller partner on Amazon. Although the API refers to this as "Inventory," I couldn't find this term in the SDK documentation. I assume that the "Catalog" namespace is the equivalent.
Update:
My custom application requires a list of the following product values:
ASINs
UPCs
SKUs
FNSKUs
I have read the documentation and found an API that returns what I need, which can be found here:
https://developer-docs.amazon.com/sp-api/docs/fba-inventory-api-v1-use-case-guide
According to the documentation, I need to create a signature in order to use the API. However, it is noted that if I use the AWS SDK, I do not need to calculate the signature myself. Therefore, I understand that the best practice is to use the AWS SDK.
I have the necessary IAM role permissions and the SP-API app has been published. I am currently attempting to use the AWS SDK.
I have made some changes based on recommendations, but I am not completely sure what else I need to do. Here is my current code:
```
export const /*bundle */ start = async () => {
const client = new MarketplaceCatalogClient({
region: REGION,
credentials: {
accessKeyId: ACCESS_KEY_ID,
secretAccessKey: ACCESS_SECRET_KEY,
},
});
const params = {
/** input parameters */
};
const answer = await client.send(
new ListEntitiesCommand({ Catalog: "AWSMarketplace", EntityType: "ContainerProduct" })
);
console.log(100, answer);
return answer;
};
```
I got the next answer with "AmiProduct" or "ContainerProduct":
{
'$metadata': {
httpStatusCode: 200,
requestId: '91fc5fed-6cdc-42d6-97ec-1ed3cc9d5796',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
EntitySummaryList: []
}
I'm having difficulty understanding how to correctly implement this. Any guidance would be greatly appreciated.
The docs should be better. I spent a good 15 mins on the docs at https://docs.aws.amazon.com/marketplace-catalog/latest/api-reference/welcome.html and failed to find a full list of valid EntityType values.
Some EntityType values are documented here: https://docs.aws.amazon.com/marketplace-catalog/latest/api-reference/seller-products.html
AmiProduct
ContainerProduct
It looks like these types correspond to the product types in the index of the seller guide here -> https://docs.aws.amazon.com/marketplace/latest/userguide/machine-learning-products.html. It's not clear what the other valid values are.
Some other EntityType values are documented here: https://docs.aws.amazon.com/marketplace-catalog/latest/api-reference/private-marketplace.html
Experience
Procurement Policy
It looks the way to go for now is to scrounge these valid values from examples in the docs https://docs.aws.amazon.com/marketplace-catalog/latest/api-reference/welcome.html. Not the best developer experience :grimace:
Assuming you are a seller, that you have registered successfully with your AWS account. You can then use Marketplace APIs.
To use them, you have to create an IAM role or a user with policies to grant access to invoke the selected APIs like listEntities, describeEntity, etc.
Here I again assume you have the Cognito authorized credentials if using AWS SDK.
Now to view the list of products successfully published, you use listEntites command.
You can only view AMI or Containter product types. Read here.
It uses minimum two required parameters Catalog and EntityType. The former has a fixed value AWSMarketplace, and latter can have a value either AmiProduct or ContainerProduct.
To get a detailed information about a specific product, you use describeEntity command. It takes minimum 2 required parameters Catalog and EntityID.
The former again has a fixed value AWSMarketplace. For latter, you'll obtain it from the listEntites response.

How to save a document with a dynamic id into Cloud Firestore? Always changing

I am using Cloud Firestore as my database
This is my form codes on my webpage that creates a new document into my Cloud Firestore collection called "esequiz". So how do I code it in such a way that it always plus 1 to the number of documents there are in the database? And also set a limit to having the amount of documents inside the database
form.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('esequiz').add({
question: form.question.value,
right: form.right.value,
wrong: form.wrong.value
});
form.question.value = '';
form.right.value = '';
form.wrong.value = '';
});
It currently works but it will show up as an auto generated ID. How do I make it carry on from the numbers, like as my current documents? When i save I would like it to read the current last document id, OR simply count the number of documents, then just + 1
Insight from Andrei Cusnir, counting documents in Cloud Firestore is not supported.
Now I am trying Andrei's approach 2, to query documents in descending order, then using .limit to retrieve the first one only.
UPDATED
form.addEventListener('submit', (e) => {
e.preventDefault();
let query = db.collection('esequiz');
let getvalue = query.orderBy('id', 'desc').limit(1).get();
let newvalue = getvalue + 1;
db.collection('esequiz').doc(newvalue).set({
question: form.question.value,
right: form.right.value,
wrong: form.wrong.value
});
form.question.value = '';
form.right.value = '';
form.wrong.value = '';
});
No more error, but instead, the code below returns [object Promise]
let getvalue = query.orderBy('id', 'desc').limit(1).get();
So when my form saves, it saves as [object Promise]1, which I don't know why it is like this. Can someone advise me on how to return the document id value instead of [object Promise]
I think it is because I did specify to pull the document id as the value, how do I do so?
UPDATED: FINAL SOLUTION
Played around with the codes from Andrei, and here are the final codes that works. Much thanks to Andrei!
let query = db.collection('esequiz');
//let getvalue = query.orderBy('id', 'desc').limit(1).get();
//let newvalue = getvalue + 1;
query.orderBy('id', 'desc').limit(1).get().then(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
var newID = documentSnapshot.id;
console.log(`Found document at ${documentSnapshot.ref.path}`);
console.log(`Document's ID: ${documentSnapshot.id}`);
var newvalue = parseInt(newID, 10) + 1;
var ToString = ""+ newvalue;
db.collection('esequiz').doc(ToString).set({
id: newvalue,
question: form.question.value,
right: form.right.value,
wrong: form.wrong.value
});
});
});
If I understood correctly you are adding data to the Cloud Firestore and each new document will have as name an incremental number.
If you query all the documents and then count how many are of them, then you are going to end up with many document reads as the database increases. Don't forget that Cloud Firestore is charging per document Read and Write, therefore if you have 100 documents and you want to add new document with ID: 101, then with the approach of first reading all of them and then counting them will cost you 100 Reads and then 1 Write. The next time it will cost you 101 Reads and 1 Write. And it will go on as your database increases.
The way I see is from two different approaches:
Approach 1:
You can have a single document that will hold all the information of the database and what the next name should be.
e.g.
The structure of the database:
esequiz:
0:
last_document: 2
1:
question: "What is 3+3?
right: "6"
wrong: "0"
2:
question: "What is 2+3?
right: "5"
wrong: "0"
So the process will go as follows:
Read document "/esequiz/0" Counts as 1 READ
Create new document with ID: last_document + 1 Counts as 1 WRITE
Update the document that holds the information: last_document = 3; Counts as 1 WRITE
This approach cost you 1 READ and 2 WRITES to the database.
Approach 2:
You can load only the last document from the database and get it's ID.
e.g.
The structure of the database (Same as before, but without the additional doc):
esequiz:
1:
question: "What is 3+3?
right: "6"
wrong: "0"
2:
question: "What is 2+3?
right: "5"
wrong: "0"
So the process will go as follows:
Read the last document using the approach described in Order and limit data with Cloud Firestore documentation. So you can use direction=firestore.Query.DESCENDING with combination of limit(1) which will give you the last document. Counts as 1 READ
Now you know the ID of the loaded document so you can create new document with ID: that will use the loaded value and increase it by 1. Counts as 1 WRITE
This approach cost you 1 READ and 1 WRITE in total to the database.
I hope that this information was helpful and it resolves your issue. Currently counting documents in Cloud Firestore is not supported.
UPDATE
In order for the sorting to work, you will also have to include the id as a filed of the document that so you can be able to order based on it. I have tested the following example and it is working for me:
Structure of database:
esequiz:
1:
id: 1
question: "What is 3+3?
right: "6"
wrong: "0"
2:
id:2
question: "What is 2+3?
right: "5"
wrong: "0"
As you can see the ID is set the same as the document's ID.
Now you can query all the documents and order based on that filed. At the same time you can only retrieve the last document from the query:
const {Firestore} = require('#google-cloud/firestore');
const firestore = new Firestore();
async function getLastDocument(){
let query = firestore.collection('esequiz');
query.orderBy('id', 'desc').limit(1).get().then(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
console.log(`Found document at ${documentSnapshot.ref.path}`);
console.log(`Document's ID: ${documentSnapshot.id}`);
});
});
}
OUTPUT:
Found document at esequiz/2
Document's ID: 2
Then you can take the ID and increase it by 1 to generate the name for your new document!
UPDATE 2
So, the initial question is about "How to store data in the Cloud Firestore with documents having incremental ID", at the moment you are facing issues of setting up Firestore with you project. Unfortunately, the new raised questions should be discussed in another Stackoverflow post as they have nothing to do with the logic of having incremental IDs for the document and it is better to keep one issue per question, to give better community support for members that are looking for a solution about particular issues. Therefore, I will try to help you, in this post, to execute a simple Node.js script and resolve the initial issue, which is storing to Cloud Firestore documents with incremental IDs. Everything else, on how to setup this in your project and how to have this function in your page, should be addressed in additional question, where you also will need to provide as much information as possible about the Framework you are using, the project setup etc.
So, lets make a simple app.js work with the logic described above:
Since you have Cloud Firestore already working, this means that you already have Google Cloud Platform project (where the Firestore relies) and the proper APIs already enabled. Otherwise it wouldn't be working.
Your guide in this tutorial is the Cloud Firestore: Node.js Client documentation. It will help you to understand all the methods you can use with the Firestore Node.js API. You can find helpful links for adding, reading, querying documents and many more operations. (I will post entire working code later in this steps. I just shared the link so you know where to look for additional features)
Go to Google Cloud Console Dashboard page. You should login with your Google account where your project with the Firestore database is setup.
On top right corner you should see 4 buttons and your profile picture. The first button is the Activate Cloud Shell. This will open a terminal on the bottom of the page with linux OS and Google Cloud SDK already install. There you can interact with your resources within GCP projects and test your code locally before using it in your projects.
After clicking that button, you will notice that the terminal will open in the bottom of your page.
To make sure that you are properly authenticated we will set up the project and authenticate the account again, even if it is already done by default. So first execute $ gcloud auth login
On the prompted question type Y and hit enter
Click on the generated link and authenticate your account on the prompted window
Copy the generated string back to the terminal and hit enter. Now you should be properly authenticated.
Then setup the project that contains Cloud Firestore database with the following command: $ gcloud config set project PROJECT_ID. Now you are ready to build a simple app.js script and execute it.
Create a new app.js file: nano app.js
Inside paste my code example that can be found in this GitHub link. It contains fully working example and many comments explaining each part therefore it is better that it is shared through GitHub link and not pasted here. Without doing any modifications, this code will execute exactly what you are trying to do. I have tested it my self and it is working.
Execute the script as: node app.js
This will give you the following error:
Error: Cannot find module '#google-cloud/firestore'
Since we are importing the library #google-cloud/firestore but haven't installed it yet.
Install #google-cloud/firestore library as follows: $ npm i #google-cloud/firestore. Described in DOC.
Execute the script again: $ node app.js.
You should see e.g. Document with ID: 3 is written.
If you execute again, you should see e.g. Document with ID: 4 is written.
All those changes should appear in your Cloud Firestore database as well. As you can see it is loading the ID of the last document, it is creating a new ID and then it creates a new document with the given arguments, while using the new generated ID as document name. This is exactly what the initial issue was about.
So I have shared with you the full code that works and does exactly what you are trying to do. Unfortunately, the other newly raised issues, should be addressed in another Stackoverflow post, as they have nothing to do with the initial issue, which is "How to create documents with incremental ID". I recommend you to follow the steps and have a working example and then try to implement the logic to your project. However, if you are still facing any issues with how to setup Firestore in your project then you can ask another question. After that you can combine both solutions and you will have working app!
Good luck!
I don't think the way you are trying to get the length of the collection is right and I am entirely not sure what is the best way to get that either. Because the method you are trying to implement will cost you a lot more as you are trying to read all the records of the collection.
But there can be alternatives to get the number you require.
Start storing the ID in the record and make the query with limit 1 and a descending sort on ID.
Store the latest number in another collection and increment that every time you create a new record, And fetch the same whenever needed.
These methods might fail if concurrent requests are being made without transactions.

Error: AADSTS500011: The resource principal named "URL" was not found in the tenant

I am trying to add an app to our SharePoint Online site using the template from https://learn.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part and we get the error below when we deploy to SharePoint and add the app/Web part to a test SharePoint site. We are using TypeScript as the template uses.
Has anyone else encountered this issue or know where to look for the issue?
Found [object Object]Driver Display External Error: Error: AADSTS500011: The resource principal named https://driverdisplayexternal.azurewebsites.net was not found in the tenant named 7018324c-9efd-4880-809d-b2e6bb1606b6. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant. Trace ID: 358b22eb-cd2c-4091-b592-5a57cbc21d00 Correlation ID: ec96d656-1a36-42e2-a2b9-3ff78efc1e2e Timestamp: 2019-10-01 16:26:06Z
We have added a call to our own client as shown below. We are not sure why the resource principal was not found. The Tenant ID's match and things seem to be set up properly for authentication.
HelloWorldWebPart.ts
...
this.context.aadHttpClientFactory
.getClient('https://driverdisplayexternal.azurewebsites.net')
.then((client: AadHttpClient): void => {
client
.get('https://driverdisplayexternal.azurewebsites.net/api/values', AadHttpClient.configurations.v1)
.then((response: HttpClientResponse): Promise < Order[] > => {
this.domElement.innerHTML += 'Received a response from Driver Display External: ' + response;
return response.json();
})
.catch(error => {
this.domElement.innerHTML += 'Driver Display External Error: ' + error;
console.error(error);
});
});
...
package-solution.json
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "helloworld-webpart-client-side-solution",
"id": "**ID**",
"version": "4.1.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false,
"webApiPermissionRequests": [
{
"resource": "DriverDisplayExternal",
"scope": "User.Read.All"
}
]
},
"paths": {
"zippedPackage": "solution/helloworld-webpart.sppkg"
}
}
Any help or direction to where the issue may be would be very appreciated. Thanks in advance!
Never used this API, but if I had to guess you need to change the value here:
.getClient('https://driverdisplayexternal.azurewebsites.net')
You can use either the client id / application id, or the application ID URI.
Sometimes this problem can occurr when you set a wrong name for the scope you are requesting access for or another configuration parameter.
I suggest to check carefully the scopes name, or maybe directly use the "copy" button from the Azure portal.
In my case it was a simple typo on a scope name.
Not sure if you figured the answer or not. When you used SPFx to request your own custom web api end point. there are couple steps:
request the permission so that you can go to SPO admin to approve the permission you request. for this case, the webApiPermissionRequests->resources needs to your AAD Application's Service Principal DisplayName. once you had AAD App create, you can run Get-AzureADServicePrincipal to get all your ServicePrincipal.
once you request the permission, from your code, you need to call AadHttpClient.getClient() to get aadHttpClient object based on the api resourceEndpoint you want, for this case, you need to pass your web api's Application ID URI which can be found from your AAD App's manifest->"identifierUris". General speaking, this should be something like api://[clientid] format. but you can change it to any unique value.
I hope it helps.
In my case i had to use the App Id when i was consuming a multi tenant API.
In my case, TenantId and ClientId were both ok.
They can be found in AAD. TenantId is right there on landing page:
and then on the same page click Applications then tab All Applications find your application there should be ClientId check if they match.
If that is still not enough, click on the application and find roles
For me, it was roles that were missing after adding those wheels started rolling again:

Error when creating charge with Parse.com Stripe API

I'm trying to create a charge with a test account on stripe.
Here is my parse cloud function:
Parse.Cloud.define("charge", function(request, response) {
var Stripe = require('stripe');
Stripe.initialize('...');
Stripe.Charges.create({
amount: 1000,
currency: "usd",
customer: "..."
},{
success: function(httpResponse) {
response.success("Purchase made!");
},
error: function(httpResponse) {
response.error("Uh oh, something went wrong");
}
});
});
I've hard coded the customerID into the function just for testing.
When I call the function from my app, I get the following error:
TypeError: Object [object Object] has no method '_each'
at request (stripe.js:58:11)
at post (stripe.js:117:12)
at Object.module.exports.Charges.create (stripe.js:157:16)
at main.js:19:18 (Code: 141, Version: 1.6.2)
Can anyone help?
#user3707419 I get the same error when trying to add a customer. Comment out that line and instead add the following:
card: stripeToken //this is the token you generated
Also, if that doesn't work, you need to revert you parse cloud code version to 1.5.0 (you are probably running the latest version 1.6.0 which does not work. The way you do this is type the following into your console:
parse jssdk 1.5.0
All of my working code on version 1.5.0 is located at this post:
Complete working Stripe + Parse.com working code on version 1.5.0
We may have to revert back even further to get customer: customer.id working I'm not sure. Let me know if you figure a different solution out. Hope this helps.
For what it's worth, your code looks very similar to my cloud code that works. However, I do not have a semicolon after the first }). Just after the final one.
If that's not the error, then i'm not very sure how to interpret your errors because i cannot see the code at the mentioned lines. Best of luck
Just so you know the real reason: Parse removed underscore lib , stripe.js thats built into parse cloud code relied on it. Hence failure like this.
Parse 1.6.X no longer supports modules, they removed them from API doc as well.

"Cannot call method 'open' of undefined" error when using indexedDB.open

I am new to IndexedDB and I am following this guide IndexedDB Tutorial I am simply trying to create a database and then be able to add a few entries. This is what I have so far.
var db = window.indexedDB.open('FriendDB', 'My Friends!');
if (db.version != '1') {
// User's first visit, initialize database (name, key, auto increment).
db.createObjectStore('Friends', 'id', true);
db.setVersion('1');
} else {
// DB already initialized.
}
var store = db.openObjectStore('Friends');
var user = store.put({name: 'Eric', gender: 'male', likes: 'html5'});
In my console I get the error "Cannot call method 'open' of undefined" how can I get this working? Also if there is a better resource online that would help me because I can't seem to find anything on the topic of IndexedDB for a newbie.
Here is the indexeddb demo from html5rocks which i have improved to work on Mozilla Firefox and added features for viewing details data and editing existing data. Inside you have explanations how to create db, insert, update and delete data in indexeddb.
https://github.com/denimf/IndexedDbToDo
Any time you see code containing a call to setVersion, it's using an outdated syntax. It was unfortunate that we had to make such a big change so late during the spec writing, but it made using IndexedDB correctly tremendously simpler so we decided it was worth it.
There is good documentation on developer.mozilla.org, even though it could definitely be improved.

Categories