57 votes

Comment importer un fichier CSV ou JSON dans le cloud firestore de firebase ?

Existe-t-il un moyen d'importer du CSV ou du JSON vers firebase cloud firestore comme dans la base de données firebase realtime ?

enter image description here

1 votes

Voir mon post pour une solution générale, traitant également les sous-collectivités.

68voto

Maciej Caputa Points 1101

Solution générale

J'ai trouvé de nombreuses prises sur un script permettant de télécharger un JSON mais aucune ne permettait les sous-collections. Mon script ci-dessus gère tout niveau d'imbrication et de sous-collections. Il gère également le cas où un document a ses propres données et sous-collections. Ceci est basé sur l'hypothèse que la collection est un tableau/objet d'objets (y compris un objet ou un tableau vide).

Pour exécuter le script, assurez-vous que vous avez installé npm et node. Ensuite, exécutez votre code en tant que node <name of the file> . Notez qu'il n'est pas nécessaire de le déployer en tant que fonction cloud.

const admin = require('../functions/node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://<your-database-name>.firebaseio.com"
});

const data = require("./fakedb.json");

/**
 * Data is a collection if
 *  - it has a odd depth
 *  - contains only objects or contains no objects.
 */
function isCollection(data, path, depth) {
  if (
    typeof data != 'object' ||
    data == null ||
    data.length === 0 ||
    isEmpty(data)
  ) {
    return false;
  }

  for (const key in data) {
    if (typeof data[key] != 'object' || data[key] == null) {
      // If there is at least one non-object item in the data then it cannot be collection.
      return false;
    }
  }

  return true;
}

// Checks if object is empty.
function isEmpty(obj) {
  for(const key in obj) {
    if(obj.hasOwnProperty(key)) {
      return false;
    }
  }
  return true;
}

async function upload(data, path) {
  return await admin.firestore()
    .doc(path.join('/'))
    .set(data)
    .then(() => console.log(`Document ${path.join('/')} uploaded.`))
    .catch(() => console.error(`Could not write document ${path.join('/')}.`));
}

/**
 *
 */
async function resolve(data, path = []) {
  if (path.length > 0 && path.length % 2 == 0) {
    // Document's length of path is always even, however, one of keys can actually be a collection.

    // Copy an object.
    const documentData = Object.assign({}, data);

    for (const key in data) {
      // Resolve each collection and remove it from document data.
      if (isCollection(data[key], [...path, key])) {
        // Remove a collection from the document data.
        delete documentData[key];
        // Resolve a colleciton.
        resolve(data[key], [...path, key]);
      }
    }

    // If document is empty then it means it only consisted of collections.
    if (!isEmpty(documentData)) {
      // Upload a document free of collections.
      await upload(documentData, path);
    }
  } else {
    // Collection's length of is always odd.
    for (const key in data) {
      // Resolve each collection.
      await resolve(data[key], [...path, key]);
    }
  }
}

resolve(data);

2 votes

Cela a bien fonctionné pour moi, c'est une bien meilleure solution (robuste et générale) que celle de Mikki. Utilisez celle-ci - la configuration est la même btw donc vous essayez soit celle-ci ou celle de Mikki très facilement - il suffit de remplacer le code actuel.

1 votes

@Maciej Caputa, Votre solution fonctionne très bien. Merci. Cependant, pouvez-vous suggérer comment modifier le fichier fakedb.json pour qu'il génère une identité automatique, plutôt qu'une séquence - 1, 2, 3, ...

1 votes

@Rinav Vous pouvez avoir un tableau traité soit comme une collection avec auto ID ou une séquence 0,1,2,3... Tout dépend de la structure de votre fichier JSON. Tout se résume au fait qu'un tableau sur une propriété avec un nombre pair d'éléments dans un chemin sera traité comme une séquence et s'il est impair, il sera traité comme une collection. J'ai mis en œuvre cette façon, mais notez que c'est en fait la seule façon conforme à la spécification de Firebase. Je me demande quand Firebase va implémenter cela dans les outils Firebase.

20voto

Mikki Points 3739

Vous avez besoin d'un script personnalisé pour le faire.

J'en ai écrit un basé sur le SDK de Firebase admin, du moment que la bibliothèque firebase ne permet pas d'importer tableaux imbriqués de données.

const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");

const data = require("./data.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://YOUR_DB.firebaseio.com"
});

data && Object.keys(data).forEach(key => {
    const nestedContent = data[key];

    if (typeof nestedContent === "object") {
        Object.keys(nestedContent).forEach(docTitle => {
            admin.firestore()
                .collection(key)
                .doc(docTitle)
                .set(nestedContent[docTitle])
                .then((res) => {
                    console.log("Document successfully written!");
                })
                .catch((error) => {
                    console.error("Error writing document: ", error);
                });
        });
    }
});

Mise à jour : J'ai écrit un article sur ce sujet - Remplir Firestore de données

1 votes

Le lien en bas de page a été très utile, et a donné beaucoup de contexte qui a rendu cette réponse beaucoup plus logique.

1 votes

Merci pour l'exemple et l'article. Cette solution a parfaitement fonctionné pour moi et a permis d'expliquer comment faire des choses en arrière-plan que quelqu'un de nouveau à Vue.js apprécie vraiment !

1 votes

Cela semble prometteur

10voto

Dan McGrath Points 9839

Il n'y en a pas, vous devrez écrire votre propre script pour le moment.

0 votes

Avez-vous des liens sur la façon d'écrire un script, merci !

3 votes

J'aime la façon dont Firebase se donne beaucoup de mal sur stackoverflow pour voir ce dont les développeurs ont besoin, mais ce serait formidable si ces efforts aboutissaient à l'ajout de fonctionnalités. Je dirais que le téléchargement JSON/CSV serait formidable :)

9voto

pasx Points 141

J'ai utilisé la solution générale fournie par Maciej Caputa. Merci ( :

Voici quelques conseils. Supposons que vous avez une application Ionic Firebase installée avec les modules de nœuds Firebase requis dans le dossier functions à l'intérieur de cette solution. Il s'agit d'une installation standard de Ionic Firebase. J'ai créé un dossier d'importation pour contenir le script et les données au même niveau.

Hiérarchie des dossiers

myIonicApp
    functions
        node_modules
            firebase-admin
ImportFolder
    script.js
    FirebaseIonicTest-a1b2c3d4e5.json
    fileToImport.json

script Paramètres

const admin = require('../myIonicApp/functions/node_modules/firebase-admin'); //path to firebase-admin module
const serviceAccount = require("./FirebaseTest-xxxxxxxxxx.json"); //service account key file

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://fir-test-xxxxxx.firebaseio.com" //Your domain from the hosting tab
});

Domain name from the Hosting tab

Création du fichier de clés du compte de service

  • Dans la console Firebase de votre projet, à côté de l'élément Project Overwiew, cliquez sur l'icône de l'engrenage et sélectionnez Users and permissions
  • Au bas de l'écran, cliquez sur Advanced permission paramètres

Accessing Google Cloud Platform Console

  • Cela ouvre un autre onglet pour la console Google Cloud Platform.
  • À gauche, sélectionnez l'élément Comptes de service
  • Créer un compte de service pour un compte de service existant

J'ai simplement ajouté une clé au compte de service par défaut de l'App Engine

La fonction Créer une clé propose de télécharger la clé dans un fichier JSON.

Creating the Service Account Key

Structure de données JSON

Pour utiliser le script fourni, la structure de données doit être la suivante :

{
  "myCollection" : {
    "UniqueKey1" : {
      "field1" : "foo",
      "field2" : "bar"
    },{
    "UniqueKey2" : {
      "field1" : "fog",
      "field2" : "buzz"
    }...
}

0 votes

Cet article et celui de Mikki m'ont aidé à faire fonctionner le script de Maciej. Ce serait bien pour la postérité si Maciej rassemblait tout cela dans sa réponse. Il y a une erreur dans votre exemple JSON ici, bien que sans elle, j'avais des problèmes avec les tableaux se comportant différemment de ce que j'attendais. L'erreur se trouve dans la ligne qui ressemble à },{. Ce { supplémentaire doit être supprimé, sauf si nous essayons de créer une sous-collection.

7voto

Dale Nguyen Points 564

Pour référence. J'ai écrit une fonction qui permet d'importer et d'exporter des données dans Firestore.

https://github.com/dalenguyen/firestore-import-export

0 votes

Simple et facile. Merci

1 votes

Mec, une solution sous-estimée parmi les autres ici. Thxx !!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X