web-dev-qa-db-fra.com

Fonctions de cloud pour Firebase: 'Erreur: impossible de gérer la requête'

J'ai envie de me tirer les cheveux; c'est soit super simple et je vais avoir gel du cerveau ou ce n'est pas si simple.

Ce que je veux

J'essaie de décompresser une URL raccourcie à l'aide de Firebase, lorsqu'un utilisateur accède à:
myapp.firebaseappurl.com/url/SHORTENEDLINK
SO ne me laissera pas ajouter une URL raccourcie

Je voudrais que la sortie soit:

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

Ce que j'ai essayé

firebase.json fichier:

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

index.js fichier:

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);
      }
    );

});

Résultat

Quand je vais à myapp.firebaseappurl.com/url/SHORTENEDLINK j'obtiens ce qui suit: 

Error: could not handle the request
12
JamesG

Vous voyez Error: could not handle the request car il y avait probablement une exception et elle a expiré.

Vérifiez vos journaux en utilisant:

firebase functions:log

Reportez-vous à docs pour plus de détails

Voici comment j'ai réussi à raccourcir l'URL

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 });
    }
  });
});

Vous pouvez suivre l'exemple hello world tout de suite et utiliser le code ci-dessus comme function.

Le code ci-dessus utilise les demandes HEAD pour jeter un coup d'œil dans le champ "En-tête" des en-têtes et décide si l'URL peut être décortiquée davantage.

Ceci est plus léger car les demandes de HEAD ne demandent aucun corps (évitant ainsi l'analyse syntaxique du corps). En outre, aucune bibliothèque tierce n'est requise!

Notez également que l'URL passée en tant que paramètre de requête. Donc, la demande serait

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

Vous évite les problèmes de réécriture d'URL. Plus sémantiquement fait un peu plus de sens.

3
Manas Jayanth

Avez-vous essayé d'utiliser la syntaxe { source: '/url/**' }?

Vous pouvez utiliser quelque chose comme ça;

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

et alors vous pouvez analyser l'URL de la demande.

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

Tout d’abord, assurez-vous de recevoir la demande correctement avec l’URL raccourcie.

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

const express = require('express');
var express_app = express();
express_app.use(body_parser.text({type: ()=>true}));
express_app.all('*', (req, res) => {
    console.log(req.path);
    res.send(JSON.stringify(req.path));
});
exports.url = functions.https.onRequest(express_app);

Maintenant, lorsque vous visitez myapp.firebaseappurl.com/url/SHORTENEDLINK, vous devriez voir SHORTENEDLINK en texte brut. Lorsque cela fonctionne, essayez la redirection.

const functions = require('firebase-functions');
const express = require('express');
const request = require('request');
var express_app = express();
express_app.use(body_parser.text({type: ()=>true}));
express_app.all('*', (req, res) => {
    var url = req.path;
    request({
        uri: uri,
        followRedirect: true
      },
      function(err, httpResponse) {
        if (err) {
          return console.error(err);
        }
        res.send(httpResponse.headers.location || uri);
      }
    );
});
exports.url = functions.https.onRequest(express_app);

De plus, il est bon d’utiliser npm install avec --save pour qu’ils se retrouvent dans le packages.json. Alors que firebase copie votre dossier node_modules, la plupart des autres plateformes SaaS exécutent npm install.

0
Chris Gunawardena

Je pense que votre code est bon. Ce que vous faites de manière incorrecte est que vous utilisez des notations Express-js dans le noeud rewrites de votre firebase.json. (la partie :item). Celles-ci ne fonctionnent pas dans la base de données en temps réel Firebase.

Donc, au lieu de faire cela, changez votre firebase.json comme suit: -

 {
  "hosting": {
    "public": "public",
    "rewrites":  {
    "source": "YOUR SHORTENED URL",
    "destination": "YOUR ORIGINAL URL"
  } 
  }
}

C’est également l’approche préconisée dans Cloud Functions for Firebase pour raccourcir les URL sample .

0
Rohan Stark