Firebase functions image download URL issues - google-cloud-functions

I am making a thumbnail image using firebase functions, however, I tried two approaches to get the downloadURL of the resulted image but both I have different problems:
The first approach: I used the code below
const signedUrls = await bucket.file(thumbFilePath).getSignedUrl({
action: "read",
expires: "03-09-2491"
});
For this approach after some days, the url is no more valid even though the expiration date is very far, I couldn't find a proper solution and in meanwhile, I found another approach so I tried it.
the second approach: I used the code below
// Uploading the thumbnail than make it public to be able to access it.
await bucket.upload(tempFilePath_des, {
destination: thumbFilePath,
metadata: metadata
});
await storage
.bucket(fileBucket)
.file(thumbFilePath)
.makePublic();
thumbURL =
"https://storage.cloud.google.com/" + fileBucket + "/" + thumbFilePath;
This approach works well when I use Google Auth, but when I use email auth the following error is thrown:
Cross-Origin Read Blocking (CORB) blocked cross-origin response
with MIME type text/html. See for more details.
Please, Any help?

I found another approach that seems to be working in this post
when uploading the image we need to give it a UUID or we can retrieve it if we want from the metadata of the file using the following
const [metadata] = await storage.bucket(fileBucket).file(filePath).getMetadata();
const uuid = metadata.metadata.firebaseStorageDownloadTokens
than we construct our URL, here my working code:
const UUID = require('uuid/v4');
let uuid = UUID()
await bucket.upload(tempFilePath_des, {
destination: thumbFilePath,
metadata : {
contentType: metdata.contentType,
metadata: {
firebaseStorageDownloadTokens: uuid
}
}
});
thumbURL =
"https://firebasestorage.googleapis.com/v0/b/" + fileBucket + "/o/" + encodeURIComponent(thumbFilePath) + "?alt=media&token=" + uuid;

Related

Upload JSON data with Google Drive API in the browser

The Google Drive API lets us upload JSON files like that:
const fileMetadata = {
name: "config.json",
};
const media = {
mimeType: "application/json",
body: fs.createReadStream("files/config.json"),
};
const file = await gapi.client.files.create({
resource: fileMetadata,
media: media,
fields: "id",
});
console.log("File Id:", file.data.id);
This works fine in Node.js, but i want this to run in the browser, however, when i pass the media argument, with the body set to a string, an empty Untitled file is created without any extension.
The filename only works when media is not present.
My question is: How to pass data for a JSON from a string, so it can be read later?
I already tried creating the file and updating it later with its ID.

ScriptApp.getService().getUrl() points to dev URL. How can I get it to point to exec production URL?

ScriptApp.getService().getUrl() is generating a dev URL. How can I make it generate the exec production URL?
How about this answer? Please think of this as just one of several possible answers.
Issue and workaround:
If you are enabling V8 runtime, in the current stage, it seems that when V8 runtime is enabled, ScriptApp.getService().getUrl() returns the dev URL like https://script.google.com/macros/s/###/dev, and when V8 runtime is disabled, it returns the exec URL like https://script.google.com/macros/s/###/exec. I think that this might be one of bugs for V8.
If you want to directly retrieve the exec URL with enabling V8, as the current workaround, how about retrieving it using the method of projects.deployments.list in Apps Script API? You can test it at "Try this API". Of course, this can be used with Google Apps Script.
Reference:
Method: projects.deployments.list
If I misunderstood your situation and this was not the direction you want, I apologize.
For those poor souls that get here, an expansion on J. G.'s comment: confirmed that the result of the getService().getURL() call is dependent on which URL (/exec or /dev) is accessed by the end-user.
There is also an explicit clarification on that (not sure if it was present before) in the method documentation, so it seems to be by-design:
If you are running the development mode web app, this returns the development mode URL.
Note that to get the correct URL you need to use a workaround suggested by Tanaike. When using it, remember that it requires a standard GCP to enable the Apps Script API (technically, you can use a default one for that, but it will only work for G Suite (Google Workspace) accounts with access to system-gsuite/apps-script/ resources).
An implementation of deployment getter would be:
const getDeployments = (options = {}) => {
const {
version = 1,
id = ScriptApp.getScriptId(),
token = ScriptApp.getOAuthToken(),
page = "",
size = 50,
type = "WEB_APP",
} = options;
const uri = `https://script.googleapis.com/v${version}/projects/${id}/deployments`;
const fullURI = `${uri}?pageSize=${size}${page ? `&pageToken=${page}` : ""}`;
const params = {
contentType: "application/json",
headers: {
Authorization: `Bearer ${token}`,
},
muteHttpExceptions: true,
method: "get",
};
const deps = [];
const response = UrlFetchApp.fetch(fullURI, params);
if (response.getResponseCode() !== 200) {
console.log(response.getContentText());
return deps;
}
const { deployments, nextPageToken } = JSON.parse(response.getContentText());
const requested = deployments.filter(({ entryPoints }) =>
entryPoints.some(({ entryPointType }) => entryPointType === type)
);
deps.push(...requested);
if (nextPageToken) {
deps.push(...getDeployments(options));
}
return deps;
};
After a successful response, check the entryPoints collection to get the deployment you need. Each entry point will have a webApp nested object - you are interested in the url property of it.

NativeScript Throwing Error Response with status: 200 for URL: null

I am using Angular4 with TypeScript version 2.2.2
My web app is running fine when I call JSON with Filters but my NativeScript app fails when I call the Filter Values as an Object but works fine when I call filter values as a string.
Error Response with status: 200 for URL: null
THIS WORKS
https://domainname.com/api/v1/searchevents?token=057001a78b8a7e5f38aaf8a682c05c414de4eb20&filter=text&search=upcoming
If the filter value and search value is STRING it works whereas if they are objects as below, it does not work
THIS DOES NOT WORK
https://api.domainname.com/api/v1/searchevents?token=057001a78b8a7e5f38aaf8a682c05c414de4eb20&filter={"limit":"12","skip":"0"}&search={"search":"","latitude":"","longitude":"","categories":"","address":"","type":"upcoming"}
The Code I used is below
getData(serverUrl, type, skip_limit) {
console.log(serverUrl);
let headers = this.createRequestHeader();
let token_value = localStorage.getItem('access_token')
let url;
var filter;
filter = '{"limit":"10","skip":"0"}'
url = this.apiUrl + serverUrl + '?token=' + token_value + '&filter=' + filter
return this.http.get(url, { headers: headers })
.map(res => res.json());
}
The URL as formed above for the API is fine and works fine. Yet the error comes Error Response with status: 200 for URL: null
CAN ANYONE HELP ME SOLVE THIS?
Looks like the issue is the "filter" values are of different type and from what you mentioned as what worked, your service is expecting a string and not an object/array. So it fails to send the proper response when it gets one. With an object in the URL, you may have to rewrite the service to read it as an object (parse the two attributes and get them individually)
To make it simple, you can make these two as two different variables in the URL. like below,
https://api.domainName.in/api/v1/oauth/token?limit=10&skip=0
Be more precise in whats happening in your question,
1) Log the exact URL and post it in the question. No one can guess what goes in "text" in your first URL.
2) Your URL which you mentioned as worked have "token" as part of path, but in the code, its a variable which will have a dynamic value from "token_value".
3) Post your service code. Especially the signature and input parsing part.
Got the solution:
All you have to do is encode the Filter and Search Parameters if it is an Object or Array using Typescript encodeURI()
var filter = '{"limit":"12","skip":"0"}'
var search = '{"search":"","latitude":"","longitude":"","categories":"","address":"","type":"upcoming"}'
var encoded_filter = encodeURI(filter);
var encoded_search = encodeURI(search);
url = this.apiUrl+serverUrl+'?token='+token_value+'&filter='+encoded_filter+'&search='+encoded_search

POST request not able to find url

I am new to nodejs as well as developing.
I am trying to get a set of data bat from a nutrition site in JSON format. If I formulate the url with my app and api keys along with criteria to paste into the browser I get a JSON data ok. When I try to send a POST request as the site asks for when the request comes back it says it cannot find the url. What it is doing is attaching ':443' to the end of the host url and like I said coming back as an error:
Error: getaddrinfo ENOTFOUND https://api.nutritionix.com/v1_1/search https://api.nutritionix.com/v1_1/search:443
What I would like to do is after the end of the url is append the 'postData'.
Here is my code:
var https = require('https');
var querystring = require('querystring');
var postData = { // Nutrionix required JSON formt
"appId":"MY_APP_KEY",
"appKey":"MY_API_KEY",
"query": "Lentils",
"fields": ["item_name", "nf_calories", "nf_serving_size_qty", "nf_serving_size_unit"],
"sort":{
"field":"score",
"order":"desc"
},
"filters":{
"item_type":"2"
}
};
console.log("This is header dta" + postData);
postBody = querystring.stringify(postData);
var post_options = {
host:"https://api.nutritionix.com/v1_1/search",
"port":"443",
method:"post",
"path":"/",
headers:{"Content-Type":"application/json",
'Content-Length': postBody.length
}
}
console.log(post_options);
var request = https.request(post_options,function(response){
return response;
});
I also am passing this data into the dev HTTP add-on in Chrome and getting back the proper response.
Any help would be appreciated.
Can you please take a look at this documentation?
It seems that you don't need to mention HTTPS
Take the port off, 443 is the default for HTTPS.

Im getting unexpectected token : for a valid JSON

I am working with ArcGIS, Esri request and I am trying to get a data from a webserver, but everytime I got the same "unexpected token : " error even when my response is correct.
Thanks in advance.
Here's my code:
require(["dojo/dom", "dojo/on", "dojo/dom-class", "dojo/_base/json", "esri/urlUtils", "esri/config", "esri/request", "dojo/domReady!"], function(dom, on, domClass, dojoJson, urlUtils, esriConfig, esriRequest) {
// fallback to proxy for non-CORS capable browsers
// esri.config.defaults.io.proxyUrl = "/arcgisserver/apis/javascript/proxy/proxy.ashx";
esriConfig.defaults.io.proxyUrl = "/proxy/proxy.ashx";
dom.byId("url").value = "http://api.citybik.es/v2/networks/dublinbikes";
dom.byId("content").value = "";
//handle the Go button's click event
on(dom.byId("submitRequest"), "click", getContent);
function getContent(){
var contentDiv = dom.byId("content");
contentDiv.value = "";
domClass.remove(contentDiv, "failure");
dom.byId("status").innerHTML = "Downloading...";
// //get the url
// var url = urlUtils.urlToObject(dom.byId("url").value);
// console.log("EL URL path",url.path)
// console.log("EL URL query",url.query)
// var requestHandle = esriRequest({
// "url": url.path,
// "content": url.query
// });
// requestHandle.then(requestSucceeded, requestFailed);
function requestSucceeded(data) {
console.log(data);
}
function requestFailed(error) {
console.log("Error: ", error.message);
}
var request = esriRequest({
url: "http://api.citybik.es/v2/networks/dublinbikes",
content: {
format: "json"
},
handleAs: "json",
callbackParamName: "retrive"
});
request.then(requestSucceeded, requestFailed);
}
}
);
Im getting:
Uncaught SyntaxError: Unexpected token : dublinbikes:2
The root problem is that you're getting esri.request a bit confused with what you're asking for, and what the server is giving back. Because you're making a request on a different domain (api.citybik.es) from where you're running the code (whatever your host is), you need to use either:
CORS
JSONP
a proxy
to get around the browser's security restrictions. There's plenty of detail on SO about these, I won't dribble on further.
Your code has two methods configured - the callbackParamName tells esri.request to use JSONP, and you've also got a proxy set just in case. The callbackParamName tells it to only use JSONP though, so the proxy is ignored.
Now the real problem, as I noted in a comment above, is that v2 of the CityBikes API doesn't actually seem to support JSONP, so your callback parameter is ignored and the server gives you back straight JSON. esri.request is expecting JSONP, and voila - unexpected token :. Requesting
http://api.citybik.es/v2/networks/dublinbikes?callback=stackoverflow
returns:
{
network: {
company: "JCDecaux",
href: "/v2/networks/dublinbikes",
....
See? No mention of our stackoverflow variable. If you look at v1 of the API instead, that DOES support JSONP. Requesting
http://api.citybik.es/dublinbikes.json?callback=stackoverflow
returns:
stackoverflow(
[
{
bikes: 1,
name: "Fenian Street",
idx: 0,
....
...and there is our stackoverflow variable. OR you can remove the callbackParamName from your esriRequest, and see if your proxy will process the JSON from the v2 address.