I'm currently trying to send a notification using the " Try this API " interface of Firebase.
I filled my Request Body with this :
{
"validateOnly": false,
"message": {
"notification": {
"body": "Body",
"title": "Title"
}
}
}
and the RequestParameters with
projects/myprojectid
I didn't check the Google API Key since my project doesn't have one, but I checked the Google OAuth 2.0.
After executing, I get this error :
{
"error": {
"code": 400,
"message": "Recipient of the message is not set.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "message",
"description": "Recipient of the message is not set."
}
]
},
{
"#type": "type.googleapis.com/google.firebase.fcm.v1.FcmError",
"errorCode": "INVALID_ARGUMENT"
}
]
}
}
After some research, I don't understand what is missing in the request. Are all the parameters mandatory for the request ?
You're not specifying who the message is for, which is what the error message is trying to tell you. You can do by either including a token key with one of more device tokens, or a topic or condition key in the JSON.
Also see the Firebase documentation on building requests to send a message for more information and examples of each of these.
I am new to cURL and Firebase. I'm trying to send a FCM test message using Powershell with the following code from https://firebase.google.com/docs/cloud-messaging/js/first-message#curl (I had to fix the position of one closing bracket)
This is the code I am using-
curl -X POST -H "Authorization: Bearer ya29.c.KpAB...." -H "Content-Type: application/json" -d '{
"message":{
"notification": {
"title": "FCM-Message",
"body": "This-is-a-message-from-FCM"
},
"webpush": {
"headers": {
"Urgency": "high"
},
"notification": {
"body": "This-is-a-message-from-FCM-to-web",
"requireInteraction": "true",
"badge": "/badge-icon.png"
}
},
"token": "fG7.....",
}
}' https://fcm.googleapis.com/v1/projects/project-f0994/messages:send
But for some reason I am getting this error:
{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED"
}
}
I can't figure out what I might be doing wrong. Thanks.
I called Hosting API referencing Deploy to your site using the Hosting REST API but I got the following response:
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
Code:
const { google } = require("googleapis");
var key = require('./service-account.json');
var jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
"https://www.googleapis.com/auth/firebase.hosting",
null
);
jwtClient.authorize(function(err, tokens) {
if (err) {
console.error(err);
return;
}
console.log(tokens.access_token);
});
Shell:
$ node main.js
ya29.c.Elp0...
$ curl -H "Content-Type: application/json" \
-H "Authorization: Bearer ya29.c.Elp0..." \
-d '{
"config": {
"headers": [{
"glob": "**",
"headers": {
"Cache-Control": "max-age=1800"
}
}]
}
}' \
https://firebasehosting.googleapis.com/v1beta1/sites/[project-id]/versions
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
The project id of service-account.json and the project id in api endpoint are the same.
On the other hand, I only got successful response when releases.list method:
$ curl -H "Authorization: Bearer ya29.c.Elp0..." \
https://firebasehosting.googleapis.com/v1beta1/sites/[project-id]/releases
{
"releases": [
...
]
}
Any tips on how to solve this problem?
Thank you.
Update:
The scope was wrong.
In the document, authorization scope is one of firebase.hosting, firebase and cloud-platform but I only got successful response when using https://www.googleapis.com/auth/cloud-platform.
I have successfully tested the first few intents of my app with my webhook in the DialogFlow console, but testing in the Simulator gives the following error:
UnparseableJsonResponse API Version 2: Failed to parse JSON response
string with 'INVALID_ARGUMENT' error: ": Cannot find field.".
NB!!!
The first thing to notice is that it refers to "API Version 2".
No requests are reaching my webhook - so it appears that this is all within Google.
Using Chrome Developer Tools, I see the Network entry that gets this error response - some details below:
Request url from Simulator: https://assistant.clients6.google.com/v1/assistant:converse?alt=json&key=A.....
NB!!!
(Note it says 'v1')
Request Payload:
{"conversationToken":"","debugLevel":1,"inputType":"KEYBOARD","locale":"en-US","mockLocation":{"city":"Mountain View","coordinates":{"latitude":37.421980615353675,"longitude":-122.08419799804688},"formattedAddress":"Googleplex, Mountain View, CA 94043, United States","zipCode":"94043"},"query":"Talk to ","surface":"PHONE"}
Response:
{
"response": "Connect the docs isn't responding right now. Try again soon.",
"conversationToken": "GidzaW11bGF0b3JfZGV2aWNlXzM3MTQxRERFM0I0Nzk1Q0ZfMDAwMDA=",
"audioResponse": "//NExAAR... encoded audio ...",
"debugInfo": {
"assistantToAgentDebug": {
"curlCommand": "curl -v 'https://api.api.ai/api/integrations/google?token=...token...' -H 'Content-Type: application/json;charset=UTF-8' -H 'Google-Actions-API-Version: 2' -H 'Authorization: ...authorization key...' -A 'Mozilla/5.0 (compatible; Google-Cloud-Functions/2.1; +http://www.google.com/bot.html)' -X POST -d '{\"user\":{\"userId\":\"...user id...\",\"locale\":\"en-US\",\"lastSeen\":\"2017-12-15T17:22:55Z\"},\"conversation\":{\"conversationId\":\"1513778713541\",\"type\":\"NEW\"},\"inputs\":[{\"intent\":\"actions.intent.MAIN\",\"rawInputs\":[{\"inputType\":\"KEYBOARD\",\"query\":\"Talk to Connect The Docs\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]}]}'",
"assistantToAgentJson": "{\"user\":{\"userId\":\"...user id...\",\"locale\":\"en-US\",\"lastSeen\":\"2017-12-15T17:22:55Z\"},\"conversation\":{\"conversationId\":\"1513778713541\",\"type\":\"NEW\"},\"inputs\":[{\"intent\":\"actions.intent.MAIN\",\"rawInputs\":[{\"inputType\":\"KEYBOARD\",\"query\":\"Talk to Connect The Docs\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]}]}"
},
"agentToAssistantDebug": {
"agentToAssistantJson": "{\"message\":\"Unexpected apiai response format: Empty speech response\",\"apiResponse\":{\"id\":\"24ddbf1c-3930-40c6-ba50-03c0935cd1d0\",\"timestamp\":\"2017-12-20T14:05:13.766Z\",\"lang\":\"en-us\",\"result\":{},\"status\":{\"code\":200,\"errorType\":\"success\"},\"sessionId\":\"1513778713541\"}}"
},
"sharedDebugInfo": [{
"name": "ResponseValidation",
"subDebugEntry": [{
"name": "UnparseableJsonResponse",
"debugInfo": "API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: \": Cannot find field.\"."
}]
}]
},
"visualResponse": {}
}
I have been informed by Google Support that I am indeed using version V2 - I initiated this in December 2017 - long after the May 2017 "cutoff date" where V2 is supposed to be the default.
Is this a Google bug? Have I missed something setting up my intents? Or is there another setting that may be causing this?
I see that other posts in the DialogFlow forum show the same problem.
Any help is appreciated.
Added on 1/9/2018:
Contents of the Debug Tab:
{
"agentToAssistantDebug": {
"agentToAssistantJson": {
"message": "Unexpected apiai response format: Empty speech response",
"apiResponse": {
"id": "64a900d2-23e8-4833-b9de-0b207f63bffc",
"timestamp": "2018-01-08T21:08:36.821Z",
"lang": "en-us",
"result": {},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "1515445716570"
}
}
},
"assistantToAgentDebug": {
"assistantToAgentJson": {
"user": {
"userId": "ABwppHFGoTJm5fKpau6WWwufKQE5UwkebooowZF7YhvD7PPY-hUfxU2_KRpB0LLNcLPyXasbXnRxXT6fniKk",
"locale": "en-US",
"lastSeen": "2018-01-05T15:53:11Z"
},
"conversation": {
"conversationId": "1515445716570",
"type": "NEW"
},
"inputs": [
{
"intent": "actions.intent.MAIN",
"rawInputs": [
{
"inputType": "VOICE",
"query": "talk to connect the docs"
}
]
}
],
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
},
"isInSandbox": true,
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
}
]
},
"curlCommand": "curl -v 'https://api.api.ai/api/integrations/google?token=0ffc8bcf72704850a4b4139d49a8d72e' -H 'Content-Type: application/json;charset=UTF-8' -H 'Google-Actions-API-Version: 2' -H 'Authorization: eyJhbGciOiJSUzI1NiIsImtpZCI6IjBhYTQ1NDFlNGM4ZWVhODQ0NjhmZTYxYTkzZmIxYzA2MzJkYjVhMGYifQ.eyJhdWQiOiJhY3RpdmUtZG9jdW1lbnQiLCJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJqdGkiOiIwY2U2OTdlNmE3NGFiZmVmZTdiYzhmMGU2ZGJlMzEyMDFjOWU3MzA5IiwiaWF0IjoxNTE1NDQ1NzE2LCJleHAiOjE1MTU0NDU4MzYsIm5iZiI6MTUxNTQ0NTQxNn0.hZNpVrH4o8ObGIvZ7BQV44nymekTWR_K4_jsDKCzgj74z57IDyUXNGEZs6KUFxBM_2FXiSoOxJUQZ1OhDRpkpQ6L4LELYN_JDhly7kgy-SLgKgLG6FZ4YV-8qOgr9Uxmr9SsG6NSXdiG7HvTrHLXIwA8K2siBNGGDWAIB691gAC8qsjsq4d3VnHMTeqlJ6mDoOtZ2xdLnJbK5B-OK-rLHEhX6K1-Z7rXQL3OgSwUtRVvYfHI3jqY83Xn3-uf06izkQhwVqH-W6X1REltrlxFTPW2h72D-st-QQ9euIpK3fn0x-z3ouQ17g-rGrPjKcOop9FejtKMT1tibxSkQ7qywQ' -A 'Mozilla/5.0 (compatible; Google-Cloud-Functions/2.1; +http://www.google.com/bot.html)' -X POST -d '{\"user\":{\"userId\":\"ABwppHFGoTJm5fKpau6WWwufKQE5UwkebooowZF7YhvD7PPY-hUfxU2_KRpB0LLNcLPyXasbXnRxXT6fniKk\",\"locale\":\"en-US\",\"lastSeen\":\"2018-01-05T15:53:11Z\"},\"conversation\":{\"conversationId\":\"1515445716570\",\"type\":\"NEW\"},\"inputs\":[{\"intent\":\"actions.intent.MAIN\",\"rawInputs\":[{\"inputType\":\"VOICE\",\"query\":\"talk to connect the docs\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"},{\"name\":\"actions.capability.WEB_BROWSER\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]}]}'"
},
"sharedDebugInfo": [
{
"name": "ResponseValidation",
"subDebugEntry": [
{
"debugInfo": "API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: \": Cannot find field.\".",
"name": "UnparseableJsonResponse"
}
]
}
]
}
Contents of the Validation Errors Tab:
UnparseableJsonResponse
API Version 2: Failed to parse JSON response string with
'INVALID_ARGUMENT' error: ": Cannot find field.".
Screenshot of welcome intent added 1/10/2018:
The problem is a combination of two things:
There are no text replies set in the Response section.
When the Intent is triggered, it does not get sent to a webhook.
As a result, Dialogflow replies to the Assistant with no text response, which is an error.
You can correct this by making sure your welcome intent does one of the following (you don't have to do both):
Set one or more text replies. These would be sent back when the Intent is called.
Check the Use webhook box under Fulfillment. This would call your webhook when the Intent is triggered. (And then make sure that your webhook returns a valid response.)
As you speculated in your comments, you could also change the Welcome Intent to one of your other Intents that you've already tested to respond. There is nothing special about this particular Welcome Intent - it was just the one created by default for you.
I have an account of an openstack swift and I can access objects in the swift using my user name and password. And my openstack swift adopt keystore to deal with auth.
Now I want to generate a token and another one can access an object in the swift only using the token. And the token will expire after a period.Can I do this? How can I do it?
First generate a token using:
$ curl -v -s -X POST $OS_AUTH_URL/auth/tokens?nocatalog
-H "Content-Type: application/json" -d '{ "auth": { "identity": { "methods": ["password"],
"password": {"user": {"domain": {"name": "'"$OS_USER_DOMAIN_NAME"'"},
"name": "'"$OS_USERNAME"'", "password": "'"$OS_PASSWORD"'"} } },
"scope": { "project": { "domain": { "name": "'"$OS_PROJECT_DOMAIN_NAME"'" },
"name": "'"$OS_PROJECT_NAME"'" } } }}' \
| python -m json.tool
Then get the toke using:
$Keystone token-get