getting 404, firebase + node.js, using "projects.locations.instances.create" - node.js

I'm trying to make an instance of a database with node.js in firebase realtime database.
My node.js route looks like this:
const axios = require('axios');
var {google} = require("googleapis");
var serviceAccount = require("paht/to/json");
router.post('/createnewdatabase', function (req, res) {
//scopes used for the create
var scopes = [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/firebase"
];
// Authenticate a JWT client with the service account.
var jwtClient = new google.auth.JWT(
serviceAccount.client_email,
null,
serviceAccount.private_key,
scopes
);
// Use the JWT client to generate an access token.
jwtClient.authorize(function(error, tokens) {
if (error) {
console.log("Error making request to generate access token:", error);
} else if (tokens.access_token === null) {
console.log("Provided service account does not have permission to generate access tokens");
} else {
var accessToken = tokens.access_token;
let apiKey = req.body.apiKey;
const config = {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + accessToken
},
};
axios({
method: 'post',
url: 'https://firebasedatabase.googleapis.com/v1beta/projects/{project-id}/locations/europe-west1',
data: {
key: apiKey,
databaseId: 'segesggseg-656-sdgsdgs',
},
config
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
res.send('POST request to the homepage')
}
});
})
I'm getting a 404 when trying to call the route. I'm guessing it's something with the tokens. The documentation is here: https://firebase.google.com/docs/reference/rest/database/database-management/rest/v1beta/projects.locations.instances/create
I can't figure it out :-)

Please consider that according to the official documetation link:
"name field - Currently the only supported location is 'us-central1'."
I was able to create an instance using the api only with empty data parameter.
'https://firebasedatabase.googleapis.com/v1beta/projects/111111111111/locations/us-central1/instances?databaseId=myinstanceiddd&validateOnly=true&key=[YOUR_API_KEY]' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{}' \
--compressed
200
{
"name": "projects/111111111111/locations/us-central1/instances/myinstanceiddd",
"project": "projects/111111111111",
"databaseUrl": "https://myinstanceiddd.firebaseio.com",
"type": "USER_DATABASE",
"state": "ACTIVE"
}

After answer above did not work for me... I was forced to read docs (https://firebase.google.com/docs/reference/rest/database/database-management/rest/v1beta/projects.locations.instances/create) word by word...
Second paragraph says that ur project needs to be on the Blaze plan in order to be able to create instance... After this doing this, it now works for me.

Related

Update "shared" state of a file/folder with google drive API

I can't resolve how to change "shared" state to false with the google drive API.
Here is what i do:
I fetch all my folders & files witch are public with [this
one][1]
(I use q:"'me' in owners and visibility != 'limited'" filter)
I take file/folder ID and put it inside [this other one][2]
Inside the response object I got this line i want to change : "shared": true
I don't where I can set it to false, is someone getting any idea?
Have a nice day
Edit: I use NodeJs (netlify function), here is my code to get my files & folders :
const { google } = require('googleapis')
const CLIENT_ID = process.env.CLIENT_ID
const CLIENT_SECRET = process.env.CLIENT_SECRET
const REDIRECT_URI = 'https://developers.google.com/oauthplayground'
const REFRESH_TOKEN = process.env.REFRESH_TOKEN
exports.handler = async () => {
const oauth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
oauth2Client.setCredentials({ refresh_token: REFRESH_TOKEN })
const drive = google.drive({
version: 'v3',
auth: oauth2Client,
})
try {
const result = await drive.files.list({
q:"'me' in owners and visibility != 'limited'"
})
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({ ...result, Body: result.toString('utf-8') })
}
} catch (e) {
console.log(e.message)
return { statusCode: 500, body: e.message }
}
}
To change visibility ("shared": true -> "shared": false),
I tried #Tanaike answer with :
const fetch = require('node-fetch')
const API_ENDPOINT_A = 'DELETE https://www.googleapis.com/drive/v3/files/'
const API_ENDPOINT_B = '/permissions/anyoneWithLink'
exports.handler = async (event) => {
try {
const itemId = '1-7ESYk_zKJ5Sdfg_z-XiuoXxrKKpHwSa' // event.queryStringParameters.itemId
const response = await fetch(API_ENDPOINT_A + itemId + API_ENDPOINT_B)
const data = await response.json()
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({ data })
}
} catch (error) {
console.log(error)
return {
statusCode: 500,
body: JSON.stringify({ error: 'Failed fetching data' })
}
}
}
But i don't know how I can pass my private info (api key...), I used OAuth 2 for fetch, should I use it too for edit visibility ?
[1]: https://developers.google.com/drive/api/v2/reference/files/list
[2]: https://developers.google.com/drive/api/v2/reference/files/patch
If I understand correctly, you are unable to see the place where you can change the file to "shared": true. If so, in the same link you provided from the official documentation you can find it in the "Request body".
From I fetch all my folders & files witch are public with this one (I use q:"'me' in owners and visibility != 'limited'" filter), when you want to change the permission of publicly shared to the restricted, you can achieve this using Drive API as follows.
Request:
Permissions: delete is used.
DELETE https://www.googleapis.com/drive/v3/files/###fileId###/permissions/anyoneWithLink
Sample curl:
curl --request DELETE \
-H 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
'https://www.googleapis.com/drive/v3/files/###fileId###/permissions/anyoneWithLink'
If the file is publicly shared and not shared with other specific users, when this request is run, "shared": true is changed to "shared": false.
Note:
If you want to remove the permission of the specific user, you can achieve this as follows.
Retrieve the permission ID using Permissions: list.
curl \
-H 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
'https://www.googleapis.com/drive/v3/files/###fileId###/permissions'
Using the retrieved permission ID, you can delete the permission as follows.
curl --request DELETE \
-H 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
'https://www.googleapis.com/drive/v3/files/###fileId###/permissions/###permissionId###'
References:
Permissions: delete
Permissions: list
Added:
From your following replying,
I actualy use nodejs for drive API, I tried the http solution, but idk how can i pass my clientId and secretId (error 500), You can find my code on my question, i edited it
When you want to achieve to delete permissions with googleapis for Node.js, you can use the following script. In this case, please include the scope of https://www.googleapis.com/auth/drive.
Sample script:
const fileId = "###"; // Please set your file ID.
const drive = google.drive({ version: "v3", auth }); // Please use your client here.
drive.permissions.delete(
{
fileId: fileId,
permissionId: "anyoneWithLink",
},
(err, res) => {
if (err) {
console.error(err);
return;
}
console.log(res.data); // In this case, no values are returned.
}
);
In this sample script, the permission of the publicly shared file is deleted.
I got it working with the following code :
const result = await drive.permissions.delete({
fileId:"YOUR FILE ID",
permissionId:"anyoneWithLink"
})
Here is the full update code :
const { google } = require('googleapis')
const CLIENT_ID = process.env.CLIENT_ID
const CLIENT_SECRET = process.env.CLIENT_SECRET
const REDIRECT_URI = 'https://developers.google.com/oauthplayground'
const REFRESH_TOKEN = process.env.REFRESH_TOKEN
exports.handler = async () => {
const oauth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
oauth2Client.setCredentials({ refresh_token: REFRESH_TOKEN })
const drive = google.drive({
version: 'v3',
auth: oauth2Client,
})
try {
const result = await drive.permissions.delete({
fileId:"YOUR FILE ID",
permissionId:"anyoneWithLink"
})
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({ ...result, Body: result.toString('utf-8') })
}
} catch (e) {
console.log(e.message)
return { statusCode: 500, body: e.message }
}
}

Imgix Purge Post Request fails for unknown reason

I wanna purge an image from the imgix cache, they have a API for that (https://docs.imgix.com/setup/purging-images)
I use axios to make the request from my nodejs backend:
const imgixKey = functions.config().imgix.key;
const headers = {
Authorization: `Bearer ${imgixKey}`,
'Content-Type': 'application/json',
};
const data = JSON.stringify({
type: 'purges',
attributes: {
url: href,
source_id: 'SOsourceId',
},
});
try {
await axios.post('https://api.imgix.com/api/v1/purge', data, { headers });
functions.logger.log('Purged Image successfully' + href);
} catch (e) {
functions.logger.error('Error removing image from cache ' + href + ' -> ' + e);
}
Error removing image from cache {stackoverflowimgpath.png} -> Error: Request failed with status code 400
The problem is other than the status code 400 there is nothing else specified, I checked the image paths and tried different Content-Type headers like in their example but that also did not work.
Since I cannot get any more information out of the response I ask for help here since I do not know how to continue.
Checking imgix documentation, the body of your request should have a data property:
curl -X POST 'https://api.imgix.com/api/v1/purge' \
--header 'Authorization: Bearer <api-key>' \
--header 'Content-Type: application/vnd.api+json' \
--data-raw '{ "data": { "attributes": { "url": "<url-to-purge>" }, "type": "purges" } }'
So, just modify your message to (adding the data property to your json object):
const data = JSON.stringify({
data: {
type: 'purges',
attributes: {
url: href,
source_id: 'SOsourceId',
},
}
});

Axios Basic Auth with API key Example in Node

There is a curl request like this:
curl -X GET --header 'Accept: application/json' --header 'Authorization: Basic [==APIKEYHERE==]' 'https://apipath.com/path?verbose=true'
I removed the APIKEY and the API path for privacy.
The curl request is working fine, I can't figure out how to convert this into an Axios request since it only needs an API key and not a username and password.
Here is the example I found:
axios.get('https://apipath.com/path?verbose=true', {}, {auth: {username: 'username', password: 'password'}})
.then(function(response) {
console.log(response.data, 'api response');
})
I'm not sure how to get this to work for my case?
The short answer to adding an X-Api-Key to an http request with axios can be summed up with the following example:
const url =
"https://someweirdawssubdomain.execute-api.us-east-9.amazonaws.com/prod/custom-endpoint";
const config = {
headers: {
"Content-Type": "application/json",
},
};
// Add Your Key Here!!!
axios.defaults.headers.common = {
"X-API-Key": "******this_is_a_secret_api_key**********",
};
const smsD = await axios({
method: "post",
url: url,
data: {
message: "Some message to a lonely_server",
},
config,
});
I was stuck for 8 hours trying to figure this out as the errors lined up in the queue, adding the key to the default headers was the only way I could get this to work.
Given the cURL command including --header 'Authorization: Basic [==APIKEYHERE==]', you know that the server wants a header sent using the Basic authentication scheme. That means that your API key is both the username and password joined by a : and encoded with Base64. So, you can decode what the username and password should be by decoding your API key with Base64 and seeing the values joined by the colon.
Consider the spec detailed on MDN: Authorization Header
So if your API key is Ym9iOnBhc3N3b3JkMQ==, and you decode it with Buffer.from("API_KEY", "base64").toString(), you would get the value bob:password1 meaning your username is bob and your password is password1 making your request:
const [username, password] = Buffer.from("YOUR_API_KEY", "base64").toString().split(":");
axios.get('https://apipath.com/path?verbose=true', {}, {
auth: {
username,
password
}
})
.then(function(response) {
console.log(response.data, 'api response');
})
You can define a function like this, then you can pass the token to header after login success.
import axios from "axios";
const setAuthToken = token => {
if (token) {
// Apply to every request
axios.defaults.headers.common["Authorization"] = token;
} else {
// Delete auth header
delete axios.defaults.headers.common["Authorization"];
}
};
axios.get('https://apipath.com/path?verbose=true', {}, {auth: {username: 'username', password: 'password'}})
.then(() => setAuthToken(response.token));

Nodejs, http post json

Here is an example post that I want to do in my Nodejs server to get ClientID and secret.
Request example:
curl --request POST \
--url https://api.opskins.com/IOAuth/CreateClient/v1/ \
--header 'authorization: Basic {{AUTH_HASH}}' \
--data name=TestApp2 \
--data redirect_uri=http://localhost:1234
Response returns JSON structured like this:
{
"status": 1,
"time": 1535408581,
"response": {
"secret": "$nGwYVda##PErKAUpG#kHQ&YA1L)A*X1",
"client": {
"client_id": "ff371b045307",
"name": "TestApp2",
"redirect_uri": "http://localhost:1234",
"time_created": 1535407757,
"has_secret": true
}
}
I am trying with request :
const request = require('request');
var headers = {
'authorization': 'Basic ***my-api-key****'
};
var dataString = 'name=TestApp2&redirect_uri=http://localhost:5000';
var options = {
url: 'https://api.opskins.com/IOAuth/CreateClient/v1/',
method: 'POST',
headers: headers,
body: dataString
};
function callback(error, response, body) {
console.log(body);
}
request(options, callback);
but getting error output like this :
{"status":401,"time":1540115259,"message":"API Key Required"}
I have been trying different codes and middlewares but couldn't make it. Also my test works perfect on Postman. I need help to post that and get my client_id and secret.
I found a way. It was really tricky for me. I needed to use my API Key and also client id.
Bellow codes worked. Thank you very much vitomadio !
I used reqclient from npm.
here is my code
var client = new RequestClient({
baseUrl:"https://api.opskins.com/IOAuth/CreateClient/",
debugRequest:true, debugResponse:true,
auth: {
user:"***My_apikey****",
}
});
var resp = client.post("v1/", {"name": "testApp2", "redirect_uri":"http://localhost:5000/"},{headers: {"authorization":"Basic **my_clientID"}}).then(response => {
// console.log(response);
});
also I am really curies and would like to know how can I do that with request.

curl req into firebase functions req

Hello I am following the instructions to implement an encryption payment from from Adyen. I am using Firebase as my backend. Now the Dokumentation want that I make a backend req like this:
curl -u "ws#Company.SomeCompany":"SomePassword" \
-H "Content-Type: application/json" \
-X POST \
--data \
'{
"additionalData": {
"card.encrypted.json":"adyenjs_0_1_4p1$..."
},
"amount" : {
"value" : 10000,
"currency" : "EUR"
},
"reference" : "Your Reference Here",
"merchantAccount" : "TestMerchant" }'\
https://pal-test.adyen.com/pal/servlet/Payment/v30/authorise
Can someone please help me to convert this curl request into an firebase functions request? For example:
exports.helloWorld = (req, res) => {
if (req.body.message === undefined) {
// This is an error case, as "message" is required
res.status(400).send('No message defined!');
} else {
// Everything is ok
console.log(req.body.message);
res.status(200).end();
}
};
You need to pass your Adyen credentials as data in http post request. Add firebase user token as Bearer token in Authroization token. So now your function will be:
exports.helloWorld = (req, res) => {
// check authorization of firebase.
if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
res.status(403).send('Unauthorized');
return;
}
const idToken = req.headers.authorization.split('Bearer ')[1];
this.admin.auth().verifyIdToken(idToken).then(decodedIdToken => {
// new read the data like below
// req.body.username , req.body.additionalData
})
};

Resources