J'ai besoin d'obtenir un fichier CSV à partir du stockage Firebase, puis de l'analyser pour pouvoir envoyer des données aux bons documents dans Firestore. J'avais une fonction de travail, mais je ne sais pas pourquoi. C'est le code qui doit analyser les données CSV. Actuellement, je ne suis pas défini dans la constante de données, donc je pense que les données du csv sont converties de manière incorrecte en utf8. Cependant, il fonctionnait avant.

exports.importCSVAppointments = functions.region('europe-west3').storage.object().onFinalize((object) => {
  const name = object.name;
  //Test if file is in correct folder and is csv file
  const nameSplit = name.split('/');
  const organisation = nameSplit[1].split('_')[1];
  const folder = nameSplit[0];
  if(folder == 'imports'){
    //Retrieve the file from firebase storage
    const storage = new Storage();
    const bucket = storage.bucket('gs://fmis-online-dev.appspot.com');
    admin.storage().bucket().file(name)
      .download(function (err, contents) {
          if (!err) {
            const convert = (from, to) => str => Buffer.from(str, from).toString(to);
            const hexToUtf8 = convert('hex', 'utf8');
            const data = hexToUtf8(contents);
            const dataSplit = data.split('\n');
            console.log(dataSplit);
            for(i=1;i<=dataSplit.length-1;i++){
              console.log('actually runs');
              //This will run for every appointment

              //Get appointment data
              const text = dataSplit[i];
              const parsedData = text.match( /\s*(\".*?\"|'.*?'|[^,]+)\s*(,|$)/g ).map( function (text) {
                let m;
                if (m = text.match(/^\s*\"(.*?)\"\s*,?$/)) return m[1]; // Double Quoted Text
                if (m = text.match(/^\s*'(.*?)'\s*,?$/)) return m[1]; // Single Quoted Text
                if (m = text.match(/^\s*(true|false)\s*,?$/)) return m[1] === "true"; // Boolean
                if (m = text.match(/^\s*((?:\+|\-)?\d+)\s*,?$/)) return parseInt(m[1]); // Integer Number
                if (m = text.match(/^\s*((?:\+|\-)?\d*\.\d*)\s*,?$/)) return parseFloat(m[1]); // Floating Number
                if (m = text.match(/^\s*(.*?)\s*,?$/)) return m[1]; // Unquoted Text
                return text;
              } );
              console.log(parsedData);

Il s'agit du fichier CSV qui doit être analysé. La première ligne est toujours le titre

subject,contactName,contactEmail,contactPhoneNumber,dateStart,dateEnd,timeStart,timeEnd,isRecurring,frequency,days,location,room,visitorType,visitorName,visitorPhoneNumber,visitorEmail,licensePlate,sendInvite
Test CSV,name,example@example.com,+31 6 12345678,26-2-2021,26-2-2021,12:00,13:00,no,,"[]",Katrien NV,2A,Cursist,Dr. Doofenschmirtz,+31 6 98765432,visitor@example.email,,no
0
Thomas Smeman 26 févr. 2021 à 13:18

1 réponse

Meilleure réponse

Étant donné que ce code est exécuté dans une fonction cloud, vous devez utiliser la "version promise" du download() méthode, comme suit:

  if (folder == 'imports') {
    //Retrieve the file from firebase storage
    const storage = new Storage();
    const bucket = storage.bucket('gs://fmis-online-dev.appspot.com');
    return admin.storage().bucket().file(name). // <==!!! see the return here
      .download()
      .then(data => {
          const contents = data[0];
  
          // ....
          
          return null;   // <==!!! see the return here
      })
      .catch(error => {
         // ....
          return null;    // <==!!! see the return here
      })
   } else {
      return null;    // <==!!! see the return here
   }

Vous trouverez dans le doc l'explication des raisons pour lesquelles il est important de revenir une Promesse, afin de gérer correctement le cycle de vie de la Fonction Cloud.


Vous ne montrez pas comment vous écrivez dans Firestore, mais vous devez inclure dans la chaîne Promises les Promesses renvoyées par les méthodes Firestore asynchrones, par exemple:

    return admin.storage().bucket().file(name). // <==!!! see the return here
      .download()
      .then(data => {
          const contents = data[0];
  
          // ....
          const parsedData = ....

          return admin.firestore()   // <==!!! see the return here
          .doc('xxx/yyyy').set( { parsedData, foo: bar });
      })
      .catch(error => {
         // ....
          return null;    // <==!!! see the return here
      })
2
Renaud Tarnec 26 févr. 2021 à 10:37