AWS Amplify: Auth has not yet been added to this project - aws-amplify

I'm not sure what I did (removed node_modules and reinstalled?) but I used to have auth configured for my AWS Amplify (v0.1.42) project and now it's gone.
My .amplifyrc is configured correctly:
{
"providers": {
"awscloudformation": {
"AuthRoleName": "xxx",
"UnauthRoleArn": "arn:aws:iam::xxx:role/xxx",
"AuthRoleArn": "arn:aws:iam::xxx:role/xxx",
"Region": "us-east-1",
"DeploymentBucketName": "xxx",
"UnauthRoleName": "xxx",
"StackName": "xxx",
"StackId": "arn:aws:cloudformation:us-east-1:xxx:stack/xxx/xxx"
}
}
}
I have an existing amplify/ directory with auth as part of the backend and #current-cloud-backend. I also have a generated src/aws-exports.js:
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
const awsmobile = {
"aws_project_region": "us-east-1",
"aws_cognito_identity_pool_id": "us-east-1:xxx",
"aws_cognito_region": "us-east-1",
"aws_user_pools_id": "us-east-1_xxx",
"aws_user_pools_web_client_id": "xxx"
};
export default awsmobile;
All of the information is correct, however when I try to execute amplify cli commands it acts like I'm a brand new user. How can I get the amplify cli to use the existing configuration in my project?
This is incredibly frustrating because I can't really afford to create everything from scratch again.

Related

Trying to figure our why Sendgrid's email API integration with Firebase Functions is returning "API key does not start with SG."

I'm trying to integrate Sendgrid's Email API with my Firebase webapp. Here is what I've done:
1 - Installed Sendgrid's Mail package
npm install #sendgrid/mail
2 - Created an API Key on my Sendgrid Account
3 - Assigned the API Key to an environment variable using Firebase's environment configuration:
firebase functions:config:set sendgrid.key=SG.xxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx_xxxxxx_xxxxxxxxxxxxxxx
4 - checked to see if the environment variable was correctly assigned:
firebase functions:config:get
result:
5 - imported sendgrid mail and set API key:
import * as sgMail from '#sendgrid/mail';
const API_KEY = functions.config().sendgrid.key
const TEMPLATE_ID = functions.config().sendgrid.template
sgMail.setApiKey(API_KEY);
6 - created a new user trigger to send a test email
export const welcomeEmail = functions.auth.user().onCreate(user => {
const msg = {
to: user.email,
from: 'contato#mycompanydomain.com.br',
templateId: TEMPLATE_ID,
dynamic_template_data: {
subject: 'test subject!',
name: user.displayName,
},
};
return sgMail.send(msg);
})
7 - Deployed firebase functions:
firebase deploy --only functions
After doing this I'd expect that at least the API key would be set correctly, but I keep getting the following error from firebase functions log:
I can't figure out what is wrong. I've tried a few things:
1- creating a new api key and starting the process all over.
2- pasting the API directly into the sgMail.setApiKey() method. like:
sgMail.setApiKey("SG.xxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx_xxxxxx_xxxxxxxxxxxxxxx")
All of which gave the same "API key does not start with SG" error.
Can you guys help me figure out what's wrong?
Versions
"#sendgrid/mail": "^7.2.1",
"firebase-admin": "^8.10.0",
"firebase-functions": "^3.8.0"
Thank you so much
For does who had the same problem, I solved it by using the new firebase package and importing the config from firebase-functions.
So my code looks like this:
import functions, { config } from "firebase-functions";
import sendgrid from "#sendgrid/mail";
const MY_SENDGRID_API_KEY = config().sendgrid.key;
sendgrid.setApiKey(MY_SENDGRID_API_KEY);

How to configure google service key json file using .env configuration

I am creating an webservice in nodejs using google service api key and during the development phase i've put the file locally and test like this ...everythink was ok.
Now i have to deploy in firebase and i have to make unvisible the configuration file .
Do you have experience how to make this using .env file ?
The configuration file is like this :
{
"type": "service_account",
"project_id": "xxxx-eeee",
"private_key_id": "xxxw342234",
"private_key": "-----BEGIN PRIVATE KEY-----client_id": "xxxxxxxxxxxx",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xxxxxxxxxxxxxxxx.iam.gserviceaccount.com"
}
Now i access the file using this code :
const translate = new Translate(
{
projectId: 'my-project-0o0o0o0o'
keyFilename: './my-project.json
}
);
Who can help me with the steps that i have to access this file without publishing the credentials in github then in firebase
UPDATED 13.02.2020
i created .env file to store there my credentials like this :
SEPA_TRANSLATE_PROJECT_ID="4354-4545"
SEPA_TRANSLATE_GOOGLE_API_KEY_TYPE="service_account"
SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_PRIVATE_KEY_ID="43434"
SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMM=\n-----END PRIVATE KEY-----\n"
SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_CLIENT_EMAIL="googletranslateaaaaapi#aaaaa-aaaa.iam.gserviceaccount.com"
SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_CLIENT_ID="34234"
SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_AUTH_URI="https://accounts.google.com/o/oauth2/auth"
SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_TOKEN_URI="https://oauth2.googleapis.com/token"
SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_AUTH_PROVIDER_X509_CERT_URL="https://www.googleapis.com/oauth2/v1/certs"
SEPA_TRANSLATE_GOOGLE_SERVICE_CLIENT_X509_CERT_URL="https://www.googleapis.com/robot/v1/metadata/x509/googletranslatewerwer%erwerwre-werwr.iam.gserviceaccount.com"
now the my-project.json file look like :
{
"type": process.env.SEPA_TRANSLATE_GOOGLE_API_KEY_TYPE,
"project_id": process.env.SEPA_TRANSLATE_PROJECT_ID,
"private_key_id": process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_PRIVATE_KEY_ID,
"private_key": process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_PRIVATE_KEY
"client_email": process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_CLIENT_EMAIL,
"client_id": process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_CLIENT_ID,
"auth_uri": process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_AUTH_URI,
"token_uri": process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_TOKEN_URI,
"auth_provider_x509_cert_url":process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_KEY_AUTH_PROVIDER_X509_CERT_URL,
"client_x509_cert_url": process.env.SEPA_TRANSLATE_GOOGLE_SERVICE_CLIENT_X509_CERT_URL
}
this json is called :
const translate = new Translate(
{
projectId: 'my-project-0o0o0o0o'
keyFilename: './my-project.json
}
);
when i test my api i got this error message now : error translate text: SyntaxError: Unexpected token p in JSON at position 13
You shouldn't use .env file on firebase cloud functions and can't use
environment data like process.env.xxxx in json file.
You should use environment configuration for firebase cloud functions.
To store environment data, you can use the firebase functions:config:set command.
To get environment data, you can use the functions.config() function.
Local setting file is .runtimeconfig.json, and run firebase functions:config:get > .runtimeconfig.json after store environment data.(firebase functions:config:set command)
See:
https://firebase.google.com/docs/functions/config-env
https://firebase.google.com/docs/functions/local-shell#install_and_configure_the_cloud_functions_shell
If you want to only use translate API then the keyFilename is not necessary and don't make .env file yourself.
You should set up translate API authentication with a firebase service account.
And to run the local, you should set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the path of the service Account JSON file that contains service account key.
export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
See:
https://github.com/googleapis/nodejs-translate#readme.
https://cloud.google.com/translate/docs/basic/setup-basic
And Could you try translate samples?
https://github.com/googleapis/nodejs-translate/tree/master/samples
https://github.com/googleapis/nodejs-translate/tree/master/samples#samples
https://github.com/googleapis/nodejs-translate/blob/master/samples/translate.js

firebase hosting blocking script due to CORS issue

I am using firebase hosting to host few scripts and trying to access them from another site. it naturally gets blocked due to CORS issues. based on my research on other forum threads etc i modified the firebase.json as below
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"headers": [ {
"source" : "**",
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
}]
}
}
which essentially allow any url to access the resources hosted here. however, on trying to run my site i still see below
Access to XMLHttpRequest at 'https://oracle-bot-sdk.firebaseapp.com//loader.json'
from origin 'https://insurance-bot.moblize.it' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
what else is needed?
In addition to your firebase.json changes for cors, your firebase functions http / https function needs to also include the cors plugin.
Example
const cors = require('cors')({origin: true});
const functions = require('firebase-functions');
const app = functions.https.onRequest((req, res) => {
cors(req, res, () => {
// Your app stuff here
// Send Response
res.status(200).send(<response data>);
});
});
Express App Example
import express from "express";
const cors = require('cors')({origin: true});
const app = express();
app.get('**', (req, res) => {
cors(req, res, () => {
// Your App Here
// Send response
res.status(200).send(<response data>);
});
});
More documentation Serve Dynamic Content with Cloud Functions - Create an HTTP function to your Hosting site (Cors is not mentioned in the documentation btw)
Is the site (https://insurance-bot.moblize.it/) that is calling to https://oracle-bot-sdk.firebaseapp.com a Firebase hosted app?
I only ask because with version 4.2+ of Firebase Tools allows you to setup Multisite hosting using the same Firebase Project. I am not sure if that would help your situation out at all. Just wanted to mention it.
In the error message:
insurance-bot.moblize.it/:1 Failed to load https://oracle-bot-sdk.firebaseapp.com//loader.json: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://insurance-bot.moblize.it' is therefore not allowed access.
I noticed an extra '/' in https://oracle-bot-sdk.firebaseapp.com//loader.json. I doubt that is the issue, but wanted to mention it.
There is something that you could try. Similar to the answers above but a little different:
"headers": [
{
"source": "*",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
}
]
Also I would read some of the info here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Access-Control-Allow-Origin If you have not already.
I hope I was able to help in some way. Let me know.
My guess that you've mixed up firebase hosting and firebase cloud functions. Firebase hosting is made for hosting static websites and web apps. As you try to access from your website that is hosted on different domain your configuration for hosting is not applied. You mentioned that you host some scripts and it sounds like cloud functions. And good old CORS headers can help to your cloud functions like:
exports.corsEnabledFunction = (req, res) => {
res.set("Access-Control-Allow-Origin", "*");
res.set("Access-Control-Allow-Methods", "GET");
res.set("Access-Control-Allow-Headers", "Content-Type");
res.set("Access-Control-Max-Age", "3600");
// Continue with function code
...
}
More info: https://cloud.google.com/functions/docs/writing/http#handling_cors_requests
Make sure you have the Blaze or Flame plan, I think Spark plan blocks external access, maybe for the same reason as it does with cloud functions
Cloud Functions for Firebase - Billing account not configured
Go to the Google Cloud Console: https://console.cloud.google.com/functions/
Click the checkbox next to the function on which you want to grant access.
Click Show Info Panel in the top right corner to show the Permissions tab.
Click Add member.
In the New members field, type allUsers.
Select the role Cloud Functions > Cloud Functions Invoker from the Select a role drop-down menu.
Click Save.
taken from: https://github.com/firebase/firebase-functions/issues/645#issuecomment-605835353
This was the best solution for me as posted above
Go to the Google Cloud Console: https://console.cloud.google.com/functions/
Click the checkbox next to the function on which you want to grant access.
Click Show Info Panel in the top right corner to show the Permissions tab.
Click Add member.
In the New members field, type allUsers.
Select the role Cloud Functions > Cloud Functions Invoker from the Select a role drop-down menu.
Click Save.
taken from: https://github.com/firebase/firebase-functions/issues/645#issuecomment-605835353
Try pasting this as it's directly from the documentation, Customize Hosting Behavior:
"hosting": {
// Add the "headers" section within "hosting".
"headers": [ {
"source" : "**/*.#(eot|otf|ttf|ttc|woff|font.css)",
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
}
}
Firebase hosting CORS doesn't work WITH custom domain.
However, CORS API works with https://yyyyyyy.web.app/ or firebaseapp.com domain

Best setup/workflow for testing and deploying an application using Google Firebase Hosting and Functions

I built a small web application (www.suntax.de) with vuejs and hosted on Google Firebase. I use the Firebase Hosting, Database and Functions. I use Functions to do some calculation on the backend.
Everything is running now, but I had some trouble getting there and some things I would like to improve regarding my workflow.
Thus, I would like to explain you what I did and where I struggle now.
First I set up the vuejs applicationd deployed it to firebase. I added my custom domain and everything was doing fine.
Later I implemented the cloud function and want to make a call from my vuejs app.
After firebase deploy, I can call this function in the browser and it just works fine:
https://us-central1-suntax-6d0ea.cloudfunctions.net/calcEEGcompensation?year=2013&month=1&size=10
Now I thought, that I just call the URL of the function from my vuejs app. But then I got the following error message:
[Error] Origin * is not allowed by Access-Control-Allow-Origin.
I was then reading that I had to add a rewritesection in the firebase.json:
Now my firebase.json looks like this:
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
// Add the following rewrites section *within* "hosting"
"rewrites": [ {
"source": "/calcEEGcompensation", "function": "calcEEGcompensation"
} ]
}
}
Now I was able to call my firebase function with the following URL:
https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10
After integrating the above URL in my vuejs application, the application is running fine after deployment to firebase server.
As I want to keep improving the application, I would like to test everything locally before deploying.
I know that I can run firebase hosting and functions locally by:
firebase serve --only functions,hosting
However, now my application has the hard coded call to my function https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10 and this again leads to the error [Error] Origin * is not allowed by Access-Control-Allow-Origin.
But also changing the URL to the local function
http://localhost:5001/suntax-6d0ea/us-central1/calcEEGcompensation?year=2013&month=1&size=10
leads to the error message
[Error] Origin * is not allowed by Access-Control-Allow-Origin.
Some further reading brought me to the solution with cors. So I changed my function to:
const functions = require('firebase-functions');
const cors = require('cors')({origin: true});
exports.calcEEGcompensation = functions.https.onRequest((req, res) => {
cors(req, res, () => {
const yearOfCommissioning = req.query.year;
const monthOfCommissioning = req.query.month;
const pvsystemsize = req.query.size;
...
res.send("hello");
});
});
This helped and everything works now:
- The deployed application is still running fine.
- I can run the application locally while calling the local function as well as the deployed function. I just have to change the URL of the function.
But this is now my question:
Can I solve this issue in a better way? If I test the vuejs application and the function locally, I have to change the function URL before deployment. And then I have to change it back while testing locally.
I was not able to test my application and function locally without cors.
My ideal solution would be to have a setup, that can be fully tested locally and which can be easily deployed with firebase deploy without any changes of URLs. Is this possible?
Thanks and best regards,
Christoph
I found the solution which is pretty simple and does exactly what I want. I have no idea why I did not figure it out before.
Here is what I did:
I just call the relative URL from my firebase hosting:
calcEEGcompensation?year=2013&month=1&size=10
and everything works fine if the rewrites are properly set in firebase.json:
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
// Add the following rewrites section *within* "hosting"
"rewrites": [ {
"source": "/calcEEGcompensation", "function": "calcEEGcompensation"
} ]
}
}
After setting up everything like this, I can just execute firebase serve --only functions,hosting and I can test everything locally.
After executing firebase deploy, everything runs smoothly on the server.
I do not need cors.
Thanks #wonsuc for your answers.
Update(For Firebase Hosting):
Currently there is no workaround you can solve it with Firebase Hosting SDK.
But there is alternative way you can achieve this.
Try below code in your hosting source.
if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') {
console.log('It's a local server!');
}
In my opinion, these are best way to check dev environment currently.
Therefore you should use location.hostname in your Firebase Hosting, and server.address() in Cloud Functions.
And define your Functions end point with constant variable.
const DEBUG = location.hostname === 'localhost' || location.hostname === '127.0.0.1';
const FUNCTIONS_ENDPOINT_DEV = 'http://localhost:5001/';
const FUNCTIONS_ENDPOINT_PRD = 'https://us-central1-something.cloudfunctions.net/';
const FUNCTIONS_URL_CALC = 'calcEEGcompensation?year=2013&month=1&size=10';
var endpoint;
if (DEBUG) {
endpoint = FUNCTIONS_ENDPOINT_DEV + FUNCTIONS_URL_CALC;
} else {
endpoint = FUNCTIONS_ENDPOINT_PRD + FUNCTIONS_URL_CALC;
}
Original answer(For Cloud Functions for Firebase):
Have you tried node.js net module's server.address() function?
This method will tell you if your functions code is running on localhost or real deployed server.
For examples, you can use like this.
const server = app.listen(function() {
let host = server.address().address;
let port = server.address().port;
if (!host || host === '::') {
host = 'localhost:';
}
console.log('Server is running on %s%s', host, port);
});

Openstack API Authentication

Openstack noob here. I have setup an Ubuntu VM with DevStack, and am trying to authenticate with Keystone to obtain a token to be used for subsequent Openstack API calls. The identity endpoint shown on the “API Access” page in Horizon is: http://<DEVSTACK_IP>/identity.
When I post the below JSON payload to this endpoint, I get the error get_version_v3() got an unexpected keyword argument 'auth’.
{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"name": "admin",
"domain": {
"name": "Default"
},
"password": “AdminPassword”
}
}
}
}
}
Based on the Openstack docs, I should be hitting http://<DEVSTACK_IP>/v3/auth/tokens to obtain a token, but when I hit that endpoint, I get 404 Not Found.
I'm currently using Postman for testing this, but will eventually be doing programmatically.
Does anybody have any experience with authenticating against the Openstack API that can help?
Not sure whether you want to do it in a python way, but if you do, here is a way to do it:
from keystoneauth1.identity import v3
from keystoneauth1 import session
v3_auth = v3.Password(auth_url=V3_AUTH_URL,
username=USERNAME,
password=PASSWORD,
project_name=PROJECT_NAME,
project_domain_name="default",
user_domain_name="default")
v3_ses = session.Session(auth=v3_auth)
auth_token = v3_ses.get_token()
And you V3_AUTH_URL should be http://<DEVSTACK_IP>:5000/v3 since keystone is using port 5000 as a default.
If you do have a multi-domain devstack, you can change the domains, otherwise, they should be default
Just in case you don't have the client library installed: pip install python-keystoneclient
Here is a good doc for you to read about it:
https://docs.openstack.org/keystoneauth/latest/using-sessions.html
HTH

Resources