I am getting this when I use the axois .post method and send the URL to the FireBase server.
I think the URL I got is not correct. I get it from the Offical docs of Firebase and also add the WEP API key in it. But i got the same Error again and again
` import axios from "axios";
async function createUser({email,password}){
await axios.post('https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[API KEY]',
/// at API key i added my web key but it's not wokring as error
{
email:email,
password:password,
returnSecureToken:true
}
);
}
export default createUser;
`
Related
I'm trying to connect my app to firebase but the only response I get is not the response json I need from firebase. I included my call to firebase below. Is the url not correct? The response I'm getting back is not the json object made with firebase that I created.
``
<script>
(async function call () {
console.log("hello")
const endpoint = url
console.log(endpoint)
async function initiation () {
const result = await fetch(endpoint, {mode: "no-cors"})
const data = await result
console.log(data)
}
initiation()
})()
</script>
``
is your database in us-central1?
according to documentation [1] "the form https://<"databaseName">.firebaseio.com (for us-central1 databases) or https://<"databaseName"><"region">.firebasedatabase.app (for databases in all other locations)."
If its in another region you should try with https://<"databaseName"><"region">.firebasedatabase.app
[1]https://firebase.google.com/docs/database/web/start#initialize_the_javascript_sdk
The structure within your code seems odd, if you are implementing the CDN you need to initiate your app with your project credentials, right now you are only accessing a real-time database as a public request and does not provide any additional validators as the database is most likely to have Security Rules enabled.
To request data from the endpoint, you need to also include a .json at the end of the URL https://[PROJECT_ID].firebaseio.com/users/jack/name.json
Source: https://firebase.google.com/docs/reference/rest/database#section-get
I have an app where users can create posts. There is no login or user account needed! They submit content with a form as post request. The post request refers to my api endpoint. I also have some other api points which are fetching data.
My goal is to protect the api endpoints completely except some specific sites who are allowed to request the api ( I want to accomplish this by having domain name and a secure string in my database which will be asked for if its valid or not if you call the api). This seems good for me. But I also need to make sure that my own application is still able to call the api endpoints. And there is my big problem. I have no idea how to implement this and I didn't find anything good.
So the api endpoints should only be accessible for:
Next.js Application itself if somebody does the posting for example
some other selected domains which are getting credentials which are saved in my database.
Hopefully somebody has an idea.
I thought to maybe accomplish it by using env vars, read them in getinitalprops and reuse it in my post request (on the client side it can't be read) and on my api endpoint its readable again. Sadly it doesn't work as expected so I hope you have a smart idea/code example how to get this working without using any account/login strategy because in my case its not needed.
index.js
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
export default function Home(props) {
async function post() {
console.log(process.env.MYSECRET)
const response = await fetch('/api/hello', {
method: 'POST',
body: JSON.stringify(process.env.MYSECRET),
})
if (!response.ok) {
console.log(response.statusText)
}
console.log(JSON.stringify(response))
return await response.json().then(s => {
console.log(s)
})
}
return (
<div className={styles.container}>
<button onClick={post}>Press me</button>
</div>
)
}
export async function getStaticProps(context) {
const myvar = process.env.MYSECRET
return {
props: { myvar },
}
}
api
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
const mysecret = req.body
res.status(200).json({ name: mysecret })
}
From what I understand, you want to create an API without user authentication and protect it from requests that are not coming from your client application.
First of all, I prefer to warn you, unless you only authorize requests coming from certain IPs (be careful with IP Spoofing methods which could bypass this protection), this will not be possible. If you set up an API key that is shared by all clients, reverse engineering or sniffing HTTP requests will retrieve that key and impersonate your application.
To my knowledge, there is no way to counter this apart from setting up a user authentication system.
I have written a Firebase Function that is called when a new user is created using the Firebase Authentication. It then tries to create a Stripe Customer but I get the following error in the Firebase Log:
createStripeCustomer
Error: You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/. at IncomingMessage.<anonymous> (/workspace/node_modules/stripe/lib/StripeResource.js:174:21) at Object.onceWrapper (events.js:420:28) at IncomingMessage.emit (events.js:326:22) at IncomingMessage.EventEmitter.emit (domain.js:506:15) at endReadableNT (_stream_readable.js:1241:12) at processTicksAndRejections (internal/process/task_queues.js:84:21)
The complete function is shown below and has been deployed to Firebase. The Stripe secret key is loaded from a config file:
import * as functions from "firebase-functions";
import {stripe} from "../../config";
export const createStripeCustomer = functions.auth.user().onCreate(async (user) => {
const customer = await stripe.customers.create({
email: "paying.user#example.com",
source: "src_18eYalAHEMiOZZp1l9ZTjSU0",
});
console.log("customer_Id# ", customer.id);
});
Can anyone explain why I am getting the error and how I can fix the problem?
Many thanks.
I fixed my own problem. The secret key was incorrectly labelled so it wasn't being loaded properly.
I have 2 projects which are using the same code like this:
Auth.signUp({ username, password, attributes })
.then(data => console.log(data))
.catch(error => console.log(error))
.finally(() => console.log('done'));
Just like this: https://aws-amplify.github.io/docs/js/authentication#sign-up
Here is the problem show out:
In my old project, everything is ok, just 1 request is sign up send to AWS and got some data from it: https://cognito-idp.ap-southeast-2.amazonaws.com/
In my new project, I have another request go to AWS after the sign up request. There are:
https://cognito-idp.ap-southeast-2.amazonaws.com/
And : https://cognito-identity.ap-southeast-2.amazonaws.com/ which is after the first one and its response is :
message: "Unauthenticated access is not supported for this identity pool."
__type: "NotAuthorizedException"
After that, I got the error in console: Error: No credentials, applicationId or region.
Not sure why is the old project is working fine but with this one, this error show up. Is it because the different in amplify ?
Thanks.
I think the problem is with the Analytics package of AWS from my understanding of this link. Disabling it like so worked for me
import config from './aws-exports';
Amplify.configure({
...config,
Analytics: {
disabled: true
}
});
I solved it by using
import Amplify from '#aws-amplify/core';
import Auth from '#aws-amplify/auth';
istead of
import Amplify, { Auth } from 'aws-amplify';
How can I properly simulate a cloud function locally so that it has all data as when being invoked on firebase servers? (e.g. the context.auth)
I am serving my project with firebase serve, it runs ok on http://localhost:5000/, however, my cloud functions are being called from https://us-central1-<my-app>.cloudfunctions.net/getUser. (The function is not even deployed.)
To avoid XY problem, I am trying to debug my function, but calling it from firebase shell results in context.auth being undefined, same when calling via postman from http://localhost:5000/<my-app>/us-central1/getUser.
This is my ./functions/src/index.ts file
import * as functions from 'firebase-functions'
import admin from 'firebase-admin'
import { inspect } from 'util'
admin.initializeApp()
export const getUser = functions.https.onCall((data, context) => {
console.debug('== getUser called =========================================')
console.log('getUser', inspect(data), inspect(context.auth))
return admin.database().ref('userRights/admin').child(context.auth.uid).once('value', snapshot => {
console.log(snapshot.val())
if (snapshot.val() === true) {
return 'OK'
// return {status: 'OK'}
} else {
return 'NOK'
// return {status: 'error', code: 401, message: 'Unauthorized'}
}
})
})
file ./firebase.functions.ts
import { functions } from '~/firebase'
export const getUser = functions.httpsCallable('getUser')
Consumer ./src/pages/AdminPanel/index.tsx
import { getUser } from '~/firebase.functions'
//...
getUser({myDataX: 'asd'}).then(response => console.debug('response', response))
UPDATE - April/2021
As of April/2021, method useFunctionsEmulator has been deprecated. It is suggested to use method useEmulator(host, port) instead.
Original post:
By default, firebase serve sends queries to CLOUD function instead of localhost, but it is possible to change it to to point to localhost.
#gregbkr found a workaround for that at this github thread.
You basically add this after firebase initialization script (firebase/init.js) in html head.
<script>
firebase.functions().useFunctionsEmulator("http://localhost:5001");
</script>
Make sure to REMOVE it when deploying to SERVER
There is currently no support for local testing of callable functions like this. The team is working on a way for you to specify the URL endpoint of a callable function so that you can redirect it to a different location for testing.
Just found a workaround.
using fiddlers AutoResponder to redirect the function call to the local served function.
step 1
copy the target url of the function from the client
step 2
copy the local served function url
step 3
active the auto respoder and use the following rules
(the second rule is also importent to allow all outher requests
That worked for me, thank you #GorvGoyl!
script src="/__/firebase/init.js?useEmulator=true"></script