Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a Node.js proxy server hosted through Firebase Cloud Functions?

I have an application which uses a YouTube API key to search for videos on YouTube and display them on my page. I've just learned that it's bad to expose any secrets to the client. So, the solution I'm considering is to have the client send requests to a Firebase cloud function instead. The cloud function will serve as the proxy where my API key will be stored instead of storing it in the client.

How do I set it up?

For starters, I tried logging the request object but I'm getting a cryptic error message.

error: SUPERVISOR clientError { Error: Parse Error bytesParsed: 0, code: 'HPE_INVALID_METHOD' } connecting=false, _hadError=false, bytesRead=193, , fd=
-1, reading=true, $ref=$, onread=function onread(nread, buffer) {

Here's the GET request sent by the client that produced the error message above

https://localhost:5000/jpls-youtube-viewer/us-central1/helloWorld?part=snippet&type=video&q=Linkin+Park

Here's the repo of my application: https://github.com/jpls93/jpls-youtube-viewer

And here's the hosted site: https://jpls-youtube-viewer.firebaseapp.com/

like image 997
jpls93 Avatar asked Aug 03 '17 09:08

jpls93


Video Answer


1 Answers

I solved it by pointing the client request to my Firebase database URL then I had the Firebase database URL do the request to the YouTube REST API URL and resolve the response to my client. I had an issue with CORS, but that was simply fixed by allowing access-control-origin/methods

exports.helloWorld = functions.https.onRequest((request, response) => {
  var term = request.query.q;
  // See https://howtofirebase.com/firebase-cloud-functions-753935e80323
  // why we're requiring it inside the function
  var YT_URL = "https://www.googleapis.com/youtube/v3/search";
  const axios = require("axios");
  axios
    .get(YT_URL, {
      params: {
        part: "snippet",
        type: "video",
        key: require("./secret"),
        q: term
      }
    })
    .then(YouTubeData => {
      response.set("Access-Control-Allow-Origin", "*");
      response.set("Access-Control-Allow-Methods", "GET, POST");
      response.status(200).send(YouTubeData.data.items);
    })
    .catch(err => console.error(err));
});
like image 138
jpls93 Avatar answered Sep 28 '22 02:09

jpls93