Cloud Functions for Firebase: 'Error: could not handle the request'

50,637

Solution 1

You are seeing Error: could not handle the request since there probably was an exception and it timed out.

Check your logs using:

firebase functions:log

Refer docs for more details

Here's how I got URL unshortening to work

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const http = require('http');
const urlP = require('url');

const unshorten = (url, cb) => {
  const _r = http.request(
    Object.assign(
      {},
      urlP.parse(url),
      {
        method: 'HEAD',
      }
    ),
    function(response) {
      cb(null, response.headers.location || url);
    }
  );
  _r.on('error', cb);
  _r.end();
};

const resolveShortUrl = (uri, cb) => {
  unshorten(uri, (err, longUrl) => {
    if (longUrl === uri) {
      cb(null, longUrl);
    } else {
      resolveShortUrl(longUrl, cb);
    }
  });
};

exports.url = functions.https.onRequest((requested, response) => {
  var uri = requested.query.url;
  resolveShortUrl(uri, (err, url) => {
    if (err) {
      // handle err
    } else {
      response.send({ url });
    }
  });
});

You can follow the hello world example straight away and use the above code as your function.

Above code uses HEAD requests to peek into 'Location` field of the headers and decides if the url can be further unshortened.

This is lighter as HEAD requests ask for no body (thereby avoiding body parsing). Also, no third party lib required!

Also note that the url passed as a query param. So the request would be

http://<your_firebase_server>/url?url=<short_url>

Saves you the trouble of URL re-writes. Plus semantically makes a little more sense.

Solution 2

Did you tried using { source: '/url/**' } syntax?

You can use something like this;

{
  "hosting": {
    "public": "public",
    "rewrites": [ {
    "source": "/url/**",
    "function": "/url"
    }]
  }
}

and then you can parse the url from the request.

 exports.url = functions.https.onRequest((req, res) => { 
   // parse the url from the req and redirect to the correct link
 });

Solution 3

You should try this in the firebase.json, its worked for me:

"source": "/**",

I also tried "source": "/url/**" but its not worked.

Share:
50,637

Related videos on Youtube

JamesG
Author by

JamesG

Web Dev Tinkerer (a.k.a breaker of things).

Updated on December 13, 2020

Comments

  • JamesG
    JamesG over 3 years

    I feel like pulling my hair out; this is either super simple and i'm having brain freeze or it is not that simple.

    What I want

    I am trying to unshorten a shortened URL using firebase, when a user goes to:
    myapp.firebaseappurl.com/url/SHORTENEDLINK
    SO wont let me add a shortened URL

    I would like the output to be:

    {
      "url": "https://stackoverflow.com/questions/45420989/sphinx-search-how-to-use-an-empty-before-match-and-after-match"
    }
    

    What I have tried

    firebase.json file:

    {
      "hosting": {
        "public": "public",
        "rewrites": [ {
        "source": "/url/:item",
          "destination": "/url/:item"
        } ]
      }
    }
    

    index.js file:

    const functions = require('firebase-functions');
    
    exports.url = functions.https.onRequest((requested, response) => {
    
        var uri = requested.url;
        request({
            uri: uri,
            followRedirect: true
          },
          function(err, httpResponse) {
            if (err) {
              return console.error(err);
            }
            response.send(httpResponse.headers.location || uri);
          }
        );
    
    });
    

    Result

    When I go to myapp.firebaseappurl.com/url/SHORTENEDLINK I get the following:

    Error: could not handle the request
    
    • mohamad rabee
      mohamad rabee over 6 years
      add method : 'POST' to the request
    • JamesG
      JamesG over 6 years
      Why? The passed parameter is in the URL, so it's a GET request, right?
    • JamesG
      JamesG over 6 years
      @mohamadrabee - Also, just tried it to see if that was it. Nope. Didnt work.
    • mohamad rabee
      mohamad rabee over 6 years
      sorry my mistake
    • mohamad rabee
      mohamad rabee over 6 years
      can you share your package.json? did you have 'request' in the dependencies
    • JamesG
      JamesG over 6 years
      request is not on my package.json file but I did npm install request in the functions folder and it is there :)
    • Doug Stevenson
      Doug Stevenson over 6 years
      You can't use express-style ":wildcard" notation in rewrites. Rewrites can only be paths and ** wildcards. You can create an express app in Cloud Functions, and have that use :wildcard.
    • JamesG
      JamesG over 6 years
      @DougStevenson Hi Doug. I am afraid I am a little confused. Please could you show me an example of what I need with code? Thank you for your time. It it greatly appreciated :)
    • Jordan
      Jordan over 6 years
      @JamesG were you able to solve your issue? If so it is recommended to upvote the solution that helped you, or post your answer as the solution here to better help the community.
  • JamesG
    JamesG over 6 years
    This will not be dynamic. I want to be able to pass to the function the url as a parameter. Any thoughts?
  • Admin
    Admin over 6 years
    @Rohan The sample is meant only for goo.gl urls. Besides, url resolution can be done using HEAD requests which are more light weight compared to GET
  • JamesG
    JamesG over 6 years
    I thought a rewrite is needed to tell my firebase hosting which function to run based on which url?
  • Admin
    Admin over 6 years
  • Rohan Stark
    Rohan Stark over 6 years
    @JamesG Yes, it won't be dynamic. But you can simply save the original URL in your specified location whenever you shorten it. And for accessing the original URL, you can just add code inside your Cloud functions file to read it from the specified location during the HTTP trigger and use it as the URL for the your response. This of course won't be dynamic. But, you won't have to unshorten the url on the fly and you also won't have to include a third party application.
  • Admin
    Admin over 6 years
    @JamesG Did you get a chance to try the solution?