Receiving "Unsupported element '$[operation]'." when running a mutation - aws-amplify

I am having an issue running a mutation that was generated by the Amplify CLI.
I'm on node v14.18.1, amplify CLI 7.6.2.
I just recently migrated to the GraphQL Transformer v2.
Here is my model:
type User
#model
#auth(
rules: [
{ allow: groups, groups: ["admin"] }
{ allow: owner, ownerField: "id", operations: [read] }
]
) {
id: ID!
first_name: String
last_name: String
email: String!
customer: Customer #hasOne(fields: ["userCustomerId"])
userCustomerId: ID! #index(name: "usersByCreatedAt", queryField: "usersByCreatedAt" sortKeyFields: ["createdAt"])
createdAt: String!
isAdmin: Boolean
}
The mutation I'm calling from within AppSync:
mutation UpdateUser {
updateUser(input: {id: "asdfasdfasdf", isAdmin: true, last_name: "Franklin", first_name: "Tim", email: "tim#tim.com", userCustomerId: "my_customer"}) {
id
}
}
Error:
{
"data": {
"updateUser": null
},
"errors": [
{
"path": [
"updateUser"
],
"data": null,
"errorType": "MappingTemplate",
"errorInfo": null,
"locations": [
{
"line": 2,
"column": 3,
"sourceName": null
}
],
"message": "Unsupported element '$[operation]'."
}
]
}
Has anyone ran into this error, and how did you resolve it?
Thank you!

Check if there are any .vtl files in project_dir/amplify/backend/api/api_name/resolvers. If there are and you're not sure why/don't recognize them, back up and delete those files, deploy your local backend with amplify push, and see if the mutation succeeds.
I was getting the exact same error during a delete mutation and this resolved it for me. The Amplify CLI auto-generates templates for the API service, but overrides them with any it finds in that directory. Just make sure to back up all of those files before deleting them just in case..

Check what "Data Source" your resolver function is connected to. You can see this information in the AppSync web UI for the given resolver function. If the Data Source is not mapped to the correct place or if it's set to NONE_DS, then all of the operations for the given resolver function will fail.
This error happened to me when I accidentally connected the resolver to the RDS datasource instead of the DynamoDB one.

Related

Next-Auth with FaunaDB Dev Get Session Error

I've set up Next-Auth on my NextJS project to use FaunaDB. I've managed to get it working on my production environment, however, it seems to not be working on my development environment, which is using the Fauna Dev docker container rather than the cloud-based database.
Whenever I run the dev server, I get the following error log;
https://next-auth.js.org/errors#fauna__get_session_error [NotFound: instance not found] {
description: 'Set not found.',
requestResult: RequestResult {
method: 'POST',
path: '',
query: null,
requestRaw: '{"get":{"match":{"index":"session_by_token"},"terms":"86b962d600c3f53d41d5140de6daed654a473e670a99943d7fb301a4fc86357e"}}',
requestContent: Expr { raw: [Object] },
responseRaw: '{"errors":[{"position":[],"code":"instance not found","description":"Set not found."}]}',
responseContent: { errors: [Array] },
statusCode: 404,
responseHeaders: [Object: null prototype] {
':status': 404,
'x-txn-time': '1630008523944000',
'x-compute-ops': '1',
'x-read-ops': '0',
'x-byte-read-ops': '0',
'x-byte-write-ops': '0',
'x-write-ops': '0',
'x-query-time': '703',
'x-query-bytes-in': '121',
'x-query-bytes-out': '87',
'x-storage-bytes-read': '0',
'x-storage-bytes-write': '0',
'x-txn-retries': '0',
'x-faunadb-build': '21.08.00-4d315fa',
'content-length': '87',
'content-type': 'application/json;charset=utf-8'
},
startTime: 1630008521471,
endTime: 1630008522280
}
}
I've followed the guide to set this up and continue to get the same error. I've removed and recreated the fauna docker container several times, still the same error. I also have some data that I can access in the local Fauna Dev database, so that seems to be set up fine. Also if I change my .env.local environment variables to the ones I use on production, it all works fine, but of course is then using the cloud database.
Here's a comparison of my production and local variables, with private keys removed;
# .env.local
GOOGLE_ID=<removed>
GOOGLE_SECRET=<removed>
NEXT_PUBLIC_FAUNA_ADMIN_KEY=<removed>
NEXT_PUBLIC_FAUNA_DOMAIN=localhost
NEXT_PUBLIC_FAUNA_GRAPHQL_ENDPOINT=http://localhost:8084/graphql
NEXT_PUBLIC_FAUNA_PORT=8443
NEXT_PUBLIC_FAUNA_SCHEME=http
NEXTAUTH_URL=http://localhost:3000
# production env
GOOGLE_ID=<removed, identical to local>
GOOGLE_SECRET=<removed, identical to local>
NEXT_PUBLIC_FAUNA_ADMIN_KEY=<removed, different to local>
NEXT_PUBLIC_FAUNA_DOMAIN=db.eu.fauna.com
NEXT_PUBLIC_FAUNA_GRAPHQL_ENDPOINT=https://graphql.eu.fauna.com/graphql
NEXT_PUBLIC_FAUNA_SCHEME=https
NEXTAUTH_URL=https://dnd-compendium-five.vercel.app
And for good measure, here's my [...nextauth].ts file;
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
import * as Fauna from "faunadb";
import { FaunaAdapter } from "#next-auth/fauna-adapter";
const isProduction = process.env.NODE_ENV === "production";
const client = new Fauna.Client({
secret: process.env.NEXT_PUBLIC_FAUNA_ADMIN_KEY,
scheme: process.env.NEXT_PUBLIC_FAUNA_SCHEME === "https" ? "https" : "http",
domain: process.env.NEXT_PUBLIC_FAUNA_DOMAIN,
...(isProduction ? {} : { port: +process.env.NEXT_PUBLIC_FAUNA_PORT }),
});
export default NextAuth({
// Configure one or more authentication providers
providers: [
Providers.Google({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
// ...add more providers here
],
adapter: FaunaAdapter({ faunaClient: client }),
});
Update
Here's several documents from the production Fauna database, with personal info removed;
# accounts collection document
{
"ref": Ref(Collection("accounts"), "307944413618766018"),
"ts": 1629937528150000,
"data": {
"userId": "307944413481402562",
"providerId": "google",
"providerType": "oauth",
"providerAccountId": "110736403335097897627",
"accessToken": "ya29.a0ARrdaM_n4D6gDvzs8Mxs851r70Xs5v5HROSdcDM0HJoMP1XFhAPhFbmh46e4bfHzTbVYOhoc2W7N_0IHpV3yEW5a__Nzy8NrxWU3ns-KlxIm_oTXRVW0RyitT26uXtTq-45k6OTjakjHsinYpnof4qdXcICg",
"createdAt": Time("2021-08-26T00:25:28.101705Z"),
"updatedAt": Time("2021-08-26T00:25:28.101705Z")
}
}
# sessions collection document
{
"ref": Ref(Collection("sessions"), "308011284890124486"),
"ts": 1630001301580000,
"data": {
"userId": "307946306265940166",
"expires": Time("2021-09-25T18:08:21.521Z"),
"sessionToken": "997b45bb432cfbc05901e9a92ae9d1ac36637246277ac05ad915fb00b8fc9130",
"accessToken": "9dbec0113a46bc6a0768e1a5b7baafac65a1fb0a29568bc11562cd58ad97d5b9",
"createdAt": Time("2021-08-26T18:08:21.517447Z"),
"updatedAt": Time("2021-08-26T18:08:21.517447Z")
}
}
# users collection document
{
"ref": Ref(Collection("users"), "307946306265940166"),
"ts": 1629939333135000,
"data": {
"name": <string removed>,
"email": <string removed>,
"image": <url string removed>,
"createdAt": Time("2021-08-26T00:55:33.075553Z"),
"updatedAt": Time("2021-08-26T00:55:33.075553Z")
}
}
Which verisons of next-auth and the adapter are you using? They recently released a v4 beta and matching adapter beta's. Maybe you'll have more luck with those newer releases 👍

Firebase Firestore REST Request - Query and Filter

I have a firestore database on a firebase project. I want to make rest request for filtering or querying data with postman. I'm using "https://firestore.googleapis.com/v1/projects//databases/(default)/documents/" to get the data in a known path in my database. Here is a sample of my database structure:
users > xxxxx > messages > yyyyy> "sent":"true"
where "users" and "messages" are collections, "xxxxx" and "yyyyy"are autogenerated document ids (xxxxx is autogenerated user id)
What I want to do is to find the "xxxxx"s (users) which have >"sent":"true"< data.
I get success if I know the "xxxxx" and "yyyyy" but I don't know them because they are autogenerated and different from each other in my database and don't know how to do it.
You need to run a Query, as explained here in the documentation of the REST API.
Since you want to query all the messages sub-collections of different user documents, you need to "simulate" a Collection Group Query in your StructuredQuery. The way to do that is to set the allDescendants element to true in the CollectionSelector.
So, issuing a POST HTTP Request on the following URL will do the trick:
var URL = "https://firestore.googleapis.com/v1/projects/<your-project-id>/databases/(default)/documents:runQuery";
The body of the POST Request shall contain:
"structuredQuery": {
"from": [{
"collectionId": "messages",
"allDescendants": true
}],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "sent"
},
"op": "EQUAL",
"value": {
"stringValue": "true",
}
}
}
}
Note that you need to add a single field index to your Firestore DB, as follows:
Note also that, if your field sent is of type Boolean (and not String as shown in your question), you need to use a booleanValue element in your Value JSON element.
I am unable to get this to work for some reason.
I have a Collection called dzs which has some documents with auto generated id's.
I want to query and find a document with a specific email address.
When I try this in Postman, it returns (Error 400 Bad request)
"structuredQuery": {
"from": [{
"collectionId": "dzs",
"allDescendants": true
}],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "email"
},
"op": "EQUAL",
"value": {
"stringValue": "123#123.com",
}
}
}
}
Add the parent collection/document path to the URL:
var URL = "https://firestore.googleapis.com/v1/projects/<your-project-id>/databases/(default)/documents/users/xxxxx:runQuery";
Then make the collectionId "messages" and allDescendents false:
"structuredQuery": {
"from": [{
"collectionId": "messages",
"allDescendants": false
}],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "sent"
},
"op": "EQUAL",
"value": {
"stringValue": "true",
}
}
}
}
Source

JAGQL - Why do I need an id for a post call?

I'm using JAGQL to build a JSON API compatible express server. My database behind it is MongoDB (jsonapi-store-mongodb). I posted my question here as well: https://github.com/holidayextras/jsonapi-store-mongodb/issues/59
According to the JAGQL documentation, https://jagql.github.io/pages/project_setup/resources.html#generateid,
I am told that
generateId
By default, the server autogenerates a UUID for resources which are created without specifying an ID. To disable this behavior (for example, if the database generates an ID by auto-incrementing), set generateId to false. If the resource's ID is not a UUID, it is also necessary to specify an id attribute with the correct type. See /examples/resorces/autoincrement.js for an example of such a resource.
But when I send a POST request to one of my resources, I get this:
"jsonapi": {
"version": "1.0"
},
"meta": {},
"links": {
"self": "/myresource"
},
"errors": [
{
"status": "403",
"code": "EFORBIDDEN",
"title": "Param validation failed",
"detail": [
{
"message": "\"id\" is required",
"path": [
"id"
],
"type": "any.required",
"context": {
"key": "id",
"label": "id"
}
}
]
}
]
What am I missing?
See here for more details: https://github.com/jagql/framework/issues/106
In your resource definition, you want to add primaryKey: 'uuid':
{
resource: 'things',
handlers,
primaryKey: 'uuid',
attributes: {
...
}
}

Get CosmosDb Primary Connection String in ARM template

I have an ARM template which sources the primaryMasterKey of a cosmosDb as follows:
{
"properties": {
"enabled": true,
"siteConfig": {
"appSettings": [
{
"name": "MongoDb:CnnDetails",
"value": "[listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosdb_full')), '2015-04-08').primaryMasterKey]"
}
}
How to I modify it to get the actual connection string instead?
I've tried couple of things:
changed the word primaryMasterKey to primaryConnectionString. This gives an error saying:
'The language expression property 'primaryConnectionString' doesn't exist, available properties are 'primaryMasterKey, secondaryMasterKey, primaryReadonlyMasterKey, secondaryReadonlyMasterKey'
changed the work listKeys to listConnectionStrings. This is red underlined in my visual studio, but seems to work when put through azure devops
'The language expression property 'primaryConnectionString' doesn't exist, available properties are 'connectionStrings'
I went to https://learn.microsoft.com/en-us/rest/api/cosmos-db-resource-provider/databaseaccounts/listconnectionstrings#code-try-0 to try it out. ListKeys returns a structure like this:
{
"primaryMasterKey": "[REDACTED]",
"secondaryMasterKey": "[REDACTED]",
"primaryReadonlyMasterKey": "[REDACTED]",
"secondaryReadonlyMasterKey": "[REDACTED]"
}
so I get why the .primaryMasterKey worked. But ListConnectionStrings returns:
{
"connectionStrings": [
{
"connectionString": "mongodb://[REDACTED]:10255/?ssl=true&replicaSet=globaldb",
"description": "Primary MongoDB Connection String"
},
{
"connectionString": "mongodb://[REDACTED]:10255/?ssl=true&replicaSet=globaldb",
"description": "Secondary MongoDB Connection String"
},
{
"connectionString": "mongodb://[REDACTED]:10255/?ssl=true&replicaSet=globaldb",
"description": "Primary Read-Only MongoDB Connection String"
},
{
"connectionString": "mongodb://[REDACTED]:10255/?ssl=true&replicaSet=globaldb",
"description": "Secondary Read-Only MongoDB Connection String"
}
]
}
Not sure how to "index into it"?
Any clues gratefully received.
For anyone else finding this question and wanting a fully complete ARM Template snippet, this is what I have used and is working:
"connectionStrings": [
{
"name": "CosmosConnection",
"connectionString": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName')), '2019-12-12').connectionStrings[0].connectionString]",
"type": 3
}
]
like you normally would in almost any language:
ListConnectionStrings.connectionStrings[index].connectionString
index starts at 0.
you have a more "native" way of doing this:
first(ListConnectionStrings.connectionStrings).connectionString
but only available functions are first and last
The answer here by oatsoda is correct but it will only work if you are within the same resource group as the Cosmos DB you are getting the connection string for. If you have the scenario where you Cosmos DB is in a different resource group to the resource you are generating an ARM template for the following snippet is what I have used to generate the connection string for an App Service and is working.
"Cosmos": {
"value": "[listConnectionStrings(resourceId(parameters('cosmosResourceGroupName'),'Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbName')), '2019-12-12').connectionStrings[0].connectionString]",
"type": "Custom"
}
In the Cosmos linked ARM template named linkedTemplate_cosmos_db-gdp-event-ammi-dev-ne-001 I used the following code.
"outputs": {
"ConnectionString": {
"value": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('accountName')), '2019-12-12').connectionStrings[0].connectionString]",
"name": "CosmosConnection",
"type": "string"
}
},
and then in the ARM template (linkedTemplate_Main) that uses the output parameter, the following, e.g a function app configuration setting
"COSMOS_CONNECTION_STRING": {
"value": "[reference('linkedTemplate_cosmos_db-gdp-event-ammi-dev-ne-001').outputs.ConnectionString.value]"

How to specify the scope of Google API to get the birthday

I am trying to get the birthday from the Google API, but the retrieved data in HWIOAuthBundle do not contain it.
I am wondering if the specified scope for google plus api in config.yml is correct or not!
If not, please give a link or the corrected scope.
google:
type: google
client_id: %client_id%
client_secret: %secret_id%
scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
paths:
email: email
profilepicture: picture
I just used and tested it using Try It. I tested it with all of the different scopes.
https://www.googleapis.com/auth/plus.login Know your basic profile
info and list of people in your circles.
https://www.googleapis.com/auth/plus.me Know who you are on Google
https://www.googleapis.com/auth/userinfo.email View your email address
https://www.googleapis.com/auth/userinfo.profile View basic
information about your account
It doesn't appear to matter you get back the birthday in all of the scopes. But what does matter is that the Users Birthday must be set to public in the Account. If it's set to anything else, your circles, only you, it's not listed. This appears to be true even when you are trying to see your own information. (Sending Me.)
Update and the year is 2018
The People api now returns the birthday of the current user
People.get However i suspect its linked to google+ so if the user hasn't filled it out you probably wont get info.
GET https://people.googleapis.com/v1/{resourceName=people/*}
Send Resournce name of people/me and birthdays personFields
{
"resourceName": "people/117200475532672775346",
"etag": "%EgQBBzcuGgwBAgMEBQYHCAkKCwwiDDQwaGhWYzc3cXJBPQ==",
"birthdays": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "117200475532672775346"
}
},
"date": {
"month": 1,
"day": 6
}
},
{
"metadata": {
"source": {
"type": "ACCOUNT",
"id": "117200475532672775346"
}
},
"date": {
"year": 1971,
"month": 1,
"day": 6
}
}
]
Normally you will only get birthdays that have public visibility. To get private birthdays you need to use the https://www.googleapis.com/auth/user.birthday.read scope. See documentation for which scopes give you which data https://developers.google.com/people/v1/how-tos/authorizing#profile-scopes.

Resources