This is probably something trivial but I am new to GCP and app development.
I have an angular-ionic app that integrates with firebase (I am able to read and write to firestore) now I am trying to call a http triggered cloud python function.
In my firebase console under functions I can see that the function is present:
Request
https://europe-west6-tmaker-bd14b.cloudfunctions.net/generate_tournament8
I call the function in my app (running locally at the moment) as : generateTournament8(eventRefPath:string) and the implementation is in the following file:
import { AngularFireFunctions } from '#angular/fire/functions';
import { AlertController } from '#ionic/angular';
#Injectable({
providedIn: 'root'
})
export class CloudFunctionsService {
constructor(private firestoreFunctions: AngularFireFunctions, private alertController: AlertController) { }
generateTournament8(eventRefPath:string){
const callable = this.firestoreFunctions.httpsCallable('generate_tournament8');
var res = callable({'event_ref_path': eventRefPath });
res.subscribe(async res => {
const alert = await this.alertController.create({
header: `Time: ${res.date}`,
message: res.msg,
buttons: ['OK']
});
await alert.present();
});
}
}
when trying to call the function I get the following error in the console:
Access to fetch at 'https://us-central1-tmaker-bd14b.cloudfunctions.net/generate_tournament8' from origin 'http://localhost:8100' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
I think I am missing something trivial. Like not correct permissions. Can you help me?
You didn't share the code of your Cloud Function, but it seems that you are mixing up HTTPS Cloud Functions and callable Cloud Functions.
On one hand, based on your question title and function URL, as well as on the fact that there is no option for creating a Callable Cloud Function from the Google Cloud Console (which is used for Python Cloud Functions), your Cloud Function seems to be an HTTPS Cloud Function.
On the other hand, in your front-end code (this.firestoreFunctions.httpsCallable()), you actually define a callable Cloud Function.
You should call your HTTPS Cloud Function exactly like a "standard" REST API endpoint, either with fetch, axios or any other ionic/angular similar library.
Note that while Callable Cloud Functions are usually deployed via the Firebase CLI, it may be possible to create and deploy a Callable Cloud Function from Google Cloud Console but you would need to follow the specification for the HTTPS request and response.
As you're reporting, your function is available at:
Request
https://europe-west6-tmaker-bd14b.cloudfunctions.net/generate_tournament8
So, it looks like you chose europe-west6 as your region for cloud functions.
In order to properly configure #angular/fire, you need to set the REGION token in your root module:
// src/app/app.module.ts
import { NgModule } from '#angular/core';
import { AngularFireModule } from '#angular/fire';
import { AngularFireFunctionsModule, REGION } from '#angular/fire/functions';
import { environment } from '../environments/environment';
#NgModule({
imports: [
AngularFireModule.initializeApp(environment.firebase),
AngularFireFunctionsModule,
],
providers: [
{ provide: REGION, useValue: 'europe-west6' },
]
})
export class AppModule {
}
See: https://github.com/angular/angularfire/blob/master/docs/functions/functions.md#functions-region
Related
I have a test API under: pages\api\accounts\login.js. And I am learning the new app folder, which is still an experimental feature in Next.js (as of today).
Is it possible to move my login script into the app folder? I tried moving/renaming to app\api\accounts\login\pages.js, but when I do this:
async function handler(req, res) {
console.log(res);
}
export default handler;
I use the URL: http://localhost:3000/api/accounts/login. I get:
Server Error
Error: Cannot find module for page: /api/accounts/login
I also tried moving it to: app/api/accounts/login/page.js. But I get the same error.
As you can read on the API Routes page of the new documentation of Next.js, API routes are currently as before, meaning they should be in the pages/api folder:
API routes should still be defined in the pages/api/* directory and not moved to the app directory.
We are considering what API routes would look like in the app directory and will update this page in the future.
Some use cases where an API route was used to keep access tokens secure when calling an external API from the client can now be done directly in Server Components.
Any file inside the folder pages/api is mapped to /api/* and will be treated as an API endpoint instead of a route.
For example, the following API route pages/api/user.ts returns a json response with a status code of 200:
// pages/api/user.ts
import { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ name: 'John Doe' })
}
I'm trying to add existing backend to a new react frontend. Every time I call the API from react i get,
Uncaught (in promise) API api3ceaf69c does not exist
Client side code
function getData() {
const apiName = "api3ceaf69c";
const path = "/users";
const myInit = {
headers: {},
};
return API.get(apiName, path, myInit);
}
(async function () {
const response = await getData();
console.log(JSON.stringify(response));
})();
index.js
import { Amplify, API } from "aws-amplify";
import awsExports from "./aws-exports";
Amplify.configure(awsExports);
API.configure(awsExports);
aws-exports.json
{
"aws_cloud_logic_custom": [
{
"name": "api3ceaf69c",
"endpoint": "https://xxxxxxx.execute-api.ap-south-1.amazonaws.com/dev",
"region": "ap-south-1"
}
]
}
"aws-amplify": "^4.3.27"
Error
Error screenshot
I went through multiple answers around the same issue but none of them are working for me.
Interestingly this exact same code was working a few days back until I had to rebuild my backend due to some changes.
I thought client code used aws-exports.js to decide if the API exists. Looks like you may have checked it already. Does the xxxxxxx API from your exports file show up in the API Gateway in AWS Console? Can you invoke it from the console?
I figured out the problem finally! Issue was at the place where I'm calling Amplify.configure(aws_exports).
For some reason aws exports was not getting initialized in index.js file so I moved it closer to where I am actually calling the api, i.e. getData() function. It started working post that.
I currently have a Nestjs server setup and am attempting to perform an Axios request when one of the endpoints is hit with a GET request. Here is the controller.ts code:
#Controller()
export class TestController {
constructor(private readonly testService: TestService) {}
#Get('testData')
testData() {
return this.testService.testData();
}
}
Service.ts:
#Injectable()
export class TestService {
status(): string {
return 'OK'
}
testData(): Promise<any> {
return helper.getTestData();
}
}
Where helper.getTestData() is just a call to a helper file with the following function:
export async function getTestData(): Promise<any> {
const result = await axios({
url: tempURL,
method: 'GET',
timeout: 3000,
httpsAgent: new https.Agent({
rejectUnauthorized: false,
}),
});
I am able to hit this endpoint tempURL but encounter the following error message: Cannot read property 'Agent' of undefined. I know that the endpoint I am attempting to hit requires a cert, which is why I must include the httpsAgent argument inside the Axios request. If I don't include the httpsAgent argument, I receive the following message Error: unable to verify the first certificate in nodejs.
Is there a way to configure Nestjs to work with https? Or is there another way to handle this authorization issue inside of Nestjs? Using Postman everything works fine so I'm assuming it is a Nestjs issue. Any help is appreciated.
instead of import https from 'https'; you should use the namespace import: import * as https from 'https'; or set the esModuleInterop to true in your tsconfig file (under compilerOptions)
I want to get the TOKEN's value from an ASYNC config service in JwtStrategy's constructor super.
For example:
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private authConfig: AuthConfig) {
super({token: await authConfig.getConfig.jwtToken});
}
}
I am using AWS Secret Manager for storing sensitive values.
Here is my config file:
async getConfig() {
var sm = await SecretManager();
if('POOL_ID' in sm && sm.POOL_ID !== undefined) {
return {
region: envConfig.AWS_REGION,
userPoolId: sm.POOL_ID,
clientId: sm.APP_CLIENT_ID,
jwtToken: sm.jwtToken,
}
}
}
PS: I am forbidden to store the config variables in a .js or .ts file or even in .env file directly. I am only allowed to get the values from secret manager only. I've debugged and checked that I am getting correct values in authConfig only this is I can not use it in constructors.
You can't await in a constructor, so I think you need to have the config object injected.
You can make an AUTH_CONFIG useFactory provider that makes the call to secrets manager and returns the config object containing the token. It'll need to be an asynchronous provider to await the secrets manager call. On app startup, NestJS will wait for the config to be fetched so it can provide the results toJwtStrategy.
I've been stuck on an error that I'm not completely sure how to solve.
My application is made in Angular2 and runs completely in a webworker largely based on this tutorial http://www.syntaxsuccess.com/viewarticle/web-workers-in-angular-2.0
My first feature was an implementation of socket.io which is working perfectly(also with observables etc..) but now I want to use the Http service of Angular2 and I get the following error:
My code of the service is like this and the error arrises when I call validateAccessToken (I have to add the .js on my imports otherwise I get a 404 on the files within the webworker):
import { Injectable } from '#angular/core';
import { Http, Headers, RequestOptions, Response } from "#angular/http";
import { environment } from "../../../environments/environment.js";
import { Observable } from "rxjs/Observable.js";
import 'rxjs/add/operator/toPromise.js';
import 'rxjs/add/operator/map.js';
#Injectable()
export class AuthService {
headers: Headers;
options: RequestOptions;
url: string;
constructor(private http:Http) {
this.url = environment.authServerUrl;
}
validateAccessToken(token) {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
};
extractData(response: Response) {...}
handleError(error: any) {...}
}
I know the question is quite vague but with the information I get from the error it's not really clear what's going wrong for me.
The CookieXSRFStrategy is default enabled by Angular2 and used by http.
The webworker does not have DOM access to get the cookie to insert in the http headers. And thus throws the error Uncaught not implemented.
You should implement your own CookieXSRFStrategy strategy which at least does not throw this error ;)