Download stored files by .jpg url - firebase

Not sure the best way to ask this question, but it relates to firebase file storage
I am using a image stored on firebase but using a uri so I need the file to not be a download url but rather a url where it is still hosted on firebase.. hence something like url.jpg (something like http://i.imgur.com/rebvLRB.jpg ) rather than something that just downloads the image to your disk
Does firebase offer something like that.. I couldn't find option that will allow me to look at the image hosted on firebase.. rather than download it..
Hopefully that makes sense..

The short answer to your question is: the browser performs actions primarily based on two headers: Content-Type and Content-Disposition. If the file is an image (Content-Type: image/*) and has a Content-Disposition: attachment, the browser will download it (likely what we're doing by default). Set the Content-Type to inline instead and it will display in the browser.

You can get a download URL via ref.getDownloadURL(). There are many different options to get the reference:
// Create a reference with an initial file path and name
var storage = firebase.storage();
var pathReference = storage.ref('images/stars.jpg');
// Create a reference from a Google Cloud Storage URI
var gsReference = storage.refFromURL('gs://bucket/images/stars.jpg')
// Create a reference from an HTTPS URL
var httpsReference = storage.refFromURL('https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg');
Note that in the URL, characters are URL escaped, e.g. / becomes %20
And here's an example of calling getDownloadURL()
storageRef.child('images/stars.jpg').getDownloadURL().then(function(url) {
// `url` is the download URL for 'images/stars.jpg'
// This can be downloaded directly:
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function(event) {
var blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
// Or inserted into an <img> element:
var img = document.getElementById('myimg');
img.src = url;
}).catch(function(error) {
// Handle any errors
});
See more here: https://firebase.google.com/docs/storage/web/download-files

Related

How can I generate a url to a new AppInsights query?

I have a process that generates AppInsights telemetry. I would like to prove a link to a query in AppInsights. However, it is not the same query every time - the parameters change. I know I can share a link to an existing query, but how do I generate such a link to a new query?
In your Application Insights Query Editor, we have an option called Copy link to query. In this link we have following details:
The URL generated from this action has the following format:
https://portal.azure.com/## TENANT_ID/blade/Microsoft_Azure_Monitoring_Logs/LogsBlade/resourceId/%2Fsubscriptions%2F SUBSCRIPTION_ID %2FresourceGroups%2F< RESOURCEGROUP%2Fproviders%2Fmicrosoft.insights%2Fcomponents%2F APPLICATION INSIGHTS_INSTANCE_NAME /source/LogsBlade.AnalyticsShareLinkToQuery/q/ ENCODED
BASE 64_KQL_QUERY /timespan/TIMESPAN
I’ve emphasized in bold here the parameters of the URL. These parameters have the following values:
TENANT_ID: Your Tenant ID
SUBSCRIPTION_ID: Your Azure Subscription ID that contains the Application Insights instance.
RESOURCE_GROUP: Your Resource Group where the Application Insights instance is deployed.
APPINSIGHTS_INSTANCE_NAME: Your Application Insights instance Name.
ENCODED_KQL_QUERY: Base64 encoding of your query text zipped and URL encoded
TIMESPAN: time filter for the query (optional).
If your query has less than 1600 characters, you can also replace the q parameter in the above URL with a query parameter, and the encoded string will simply be your query plain text escaped (without zipping and encoding).
Dynamic URL it’s important to:
Take the text of your KQL query
Zip it
Encode it in Base64
A C# code that does the encoding of the KQL query is the following:
Generate the Query whatever you want and pass that into the below function to get the Encoded base 64 URL and you can add this in a base URL of application insights.
static string Encodedbase64KQLQuery(string query)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(query);
using (MemoryStream memoryStream = new MemoryStream())
{
using (GZipStream compressedStream = new GZipStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
{
compressedStream.Write(bytes, 0, bytes.Length);
}
memoryStream.Seek(0, SeekOrigin.Begin);
Byte[] bytedata = memoryStream.ToArray();
string encodedBase64Query = Convert.ToBase64String(bytedata);
return HttpUtility.UrlEncode(encodedBase64Query);
}
}
Please visit this blog which helped me a lot.
Thanks Delliganesh and Stefano from the blog link. Here is a simple JavaScript example. Be sure to replace all 4 constant values at top and the sessionId when calling the function. You can also tweak the query, but just keep in mind the 1600 character limit as described above and in the blog.
const APP_INSIGHTS_INSTANCE_NAME = "APP_INSIGHTS_INSTANCE_NAME";
const APP_INSIGHTS_RESOURCE_GROUP = "APP_INSIGHTS_RESOURCE_GROUP";
const APP_INSIGHTS_SUBSCRIPTION_ID = "APP_INSIGHTS_SUBSCRIPTION_ID";
const APP_INSIGHTS_TENANT_ID = "APP_INSIGHTS_TENANT_ID";
const getAppInsightsQueryUrl = ({ sessionId }) => {
const query = `requests | where session_Id == "${sessionId}"`;
const url = `https://portal.azure.com/##${APP_INSIGHTS_TENANT_ID}/blade/Microsoft_Azure_Monitoring_Logs/LogsBlade/resourceId/%2Fsubscriptions%2F${APP_INSIGHTS_SUBSCRIPTION_ID}%2FresourceGroups%2F${APP_INSIGHTS_RESOURCE_GROUP}%2Fproviders%2Fmicrosoft.insights%2Fcomponents%2F${APP_INSIGHTS_INSTANCE_NAME}/source/LogsBlade.AnalyticsShareLinkToQuery/query/${encodeURI(
query
)}/timespan/TIMESPAN`;
return url;
};
getAppInsightsQueryUrl({
sessionId: 'my-session-id',
})

Firebase storage with getDownloadURL is it better to retrieve a file with the url everytime needed or to download it to the client once?

In an app, an avatar could be displayed at many places.
If I use
getDownloadURL(avatarRef).then(url => {
imgList.map(img => img.src = url);
})
is my app billed every time an img download the url?
If so I think the better way is to download the image with xhr once and store it in the app like this
getDownloadURL(avatarRef).then(url => {
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
let blob;
xhr.onload = (event) => {
blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
// when the blob is returned
imgList.map(img => img.src = URL.creatObjectURL(blob);
})
You get charged every time the data for the image is read from Cloud Storage. So it's indeed best to cache images that are displayed multiple times.
But depending on where your code runs, that may already happen. For example browsers quite aggressively cache images.
If your environment doesn't yet cache the images, you can store them yourself using the download URL as the key/basis for the file name.

Google Form make POST request on submission

Is there a way to call an external API Endpoint on Google Forms every time the form is filled out?
First:
you'll need to set up your App script project and you'll do that by:
Visit script.google.com to open the script editor. (You'll need to be signed in to your Google account.) If this is the first time you've been to script.google.com, you'll be redirected to a page that introduces Apps Script. Click Start Scripting to proceed to the script editor.
A welcome screen will ask what kind of script you want to create. Click Blank Project or Close.
Delete any code in the script editor and paste in the code below.
This video and the doc will help
Second
you'll need to create an installable trigger, you can add it to the form directly or to the spreadsheet that has the responses
function setUpTrigger(){
ScriptApp.newTrigger('sendPostRequest') /* this has the name of the function that will have the post request */
.forForm('formkey') // you'll find it in the url
.onFormSubmit()
.create();
}
Check the doc
Third
create the sendPostRequest function and add the UrlFetchApp to it
function sendPostRequest(e){
// Make a POST request with form data.
var resumeBlob = Utilities.newBlob('Hire me!', 'text/plain', 'resume.txt');
var formData = {
'name': 'Bob Smith',
'email': 'bob#example.com',
'resume': resumeBlob
};
// Because payload is a JavaScript object, it is interpreted as
// as form data. (No need to specify contentType; it automatically
// defaults to either 'application/x-www-form-urlencoded'
// or 'multipart/form-data')
var options = {
'method' : 'post',
'payload' : formData
};
UrlFetchApp.fetch('https://httpbin.org/post', options);
}
Check the doc
Try something like this in your app script:
var POST_URL = "enter your webhook URL";
function onSubmit(e) {
var form = FormApp.getActiveForm();
var allResponses = form.getResponses();
var latestResponse = allResponses[allResponses.length - 1];
var response = latestResponse.getItemResponses();
var payload = {};
for (var i = 0; i < response.length; i++) {
var question = response[i].getItem().getTitle();
var answer = response[i].getResponse();
payload[question] = answer;
}
var options = {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify(payload)
};
UrlFetchApp.fetch(POST_URL, options);
};
Be sure to replace the POST_URL variable with your webhook, you can use requestcatcher.com to test this out.
Add a trigger to the script by clicking "Triggers" in the side menu
Open the menu (top-right dots)
Click in Script Editor
Paste the above code (changing the POST_URL)
Click in the clock icon (left-side menu), which means Triggers.
On the right-bottom corner, click in the blue Add trigger button (a form will show as the image below).
It should show onSubmit under Choose which function to run.
Make sure Select event type is set as On form submit.
Click Save button.
After that, submit your form and watch for the request to come in.
This is pretty straightforward with Google Scripts.
Just create a new project bound to your spreadsheet and create 2 elements:
A function that will contain all relevant data to make the call (see docs for making a HTTP request from Google Apps Script)
A trigger linked to the spreadsheet. You can set it to run each time an edit occurs or form is submitted
Voilà, your sheet will call whatever endpoint you wish on submission. You can even parse the spreadsheet to return that data to your endpoint

I am trying to zip a wav file from Firebase Storage but I am getting two errors

Pretty new user to Firebase here. I am trying to zip a .wav file from Firebase right now and I am currently stuck on using jszip in order to zip the files from the download URLs I pull from Firebase. The URLs look like this:
https://firebasestorage.googleapis.com/v0/b/instasample-d8eea.appspot.com/o/kick%2F1.wav?alt=media&token=91612541-83e5-4e82-ae1b-b56bc421e36b
Every time I click the download button on my site, this function runs. I successfully get the download URL, and put it into the var urls.
But I get an error that I am not allowed access to this file and an invalid state error. This puzzles me because I am able to manually go to the link and right click -> save target as just fine.
Thank you so much for any suggestions, go easy on me I am new to jszip and Firebase. This is my code:
function download(downloadType) {
//alert(downloadType)
var storageRef = firebase.storage().ref(downloadType + "/" + "1.wav"); //file name
//todo: get 16 random file links, use for loop for thing below
storageRef.getDownloadURL().then(function(url) {
var downloadLink = url; //download link
//////////////////////// do download stuff here ////////////////////////
var zip = new JSZip();
var count = 0;
var zipFilename = "zipFilename.zip";
var urls = [
downloadLink
];
urls.forEach(function(url){
var filename = "filename";
// loading a file and add it in a zip file
JSZipUtils.getBinaryContent(url, function (err, data) {
if(err) {
throw err; // or handle the error
}
zip.file(filename, data, {binary:true});
count++;
if (count == urls.length) {
var zipFile = zip.generate({type: "blob"});
saveAs(zipFile, zipFilename);
}
});
});
thanks to #MikeMcDonald i fixed both of these errors with this post: Firebase Storage and Access-Control-Allow-Origin
I am now getting:
Uncaught Error: This method has been removed in JSZip 3.0, please
check the upgrade guide.
Looks like I can finally move on. Thanks!

How can you get a url for every piece of data?

I am building an IM platform based on Firebase and I would like that every user got an address that directed them to the chat room.
http://chatt3r.sitecloud.cytanium.com/
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://cdn.firebase.com/v0/firebase.js"></script>
<script>
var hash; // global incase needed elsewhere
$(function() {
hash = window.location.hash.replace("#", "");;
myRootRef = new Firebase("http://xxxx.firebaseio.com");
var postingRef;
if (hash) {
// user has been given a hashed URL from their friend, so sets firebase root to that place
console.log(hash);
postingRef = new Firebase("http://xxxx.firebaseio.com/chatrooms/" + hash);
} else {
// there is no hash, so the user is looking to share a URL for a new room
console.log("no hash");
postingRef = new Firebase("http://xxxx.firebaseio.com/chatrooms/");
// push for a unique ID for the chatroom
postingRef = postingRef.push();
// exploit this unique ID to provide a unique ID host for you app
window.location.hash = postingRef.toString().slice(34);
}
// listener
// will pull all old messages up once bound
postingRef.on("child_added", function(data) {
console.log(data.val().user + ": " + data.val().message);
});
// later:
postingRef.push({"message": "etc", "user": "Jimmybobjimbobjimbobjim"});
});
</script>
</head>
That's working for me locally. You need to change xxxx to whatever URL yours is at, and add on however many characters that first part is at the .slice() bit.
Hashes.
If I understand your question correctly, you want to be able to share a URL that will allow anyone who clicks on the URL to log onto the same chatroom.
I did this for a Firebase application I made once. The first thing you need to be doing is using the .push() method. Push the room to Firebase, then use the toString() method to get the URL of the push. Some quick JS string manipulation - window.location.hash = pushRef.toString().slice(x) - where 'x' is whatever place you want to snip the URL at. window.location.hash will set the hash for you. Add the hash to the sharing URL, and then for the next step:
You will want a hash listener to check if there is already a hash when you open the page, so $(window).bind('hashchange', function() {UpdateHash()}) goes into a doc.ready function, and then...
function UpdateHash() {
global_windowHash = window.hash.replace("#", "");
// to assign the hash to a global hash variable
if (global_windowHash) {
// if there was already a hash
chatRef = new Firebase("[Your Firebase URL here]" + "/chatrooms/" + global_windowHash);
// chatRef is the global that you append the chat data to, and listen from.
} else {
// there wasn't a hash, so you can auto-create a new one here, in which case:
chatRef = new Firebase("[Your Firebase URL here]" + "/chatrooms/");
chatRef = chatRef.push();
window.location.hash = chatRef.toString().slice(x);
}
}
I hope that helps (and works :P ). If there are any questions or problems, then just ask!

Resources