Skip to content

Instantly share code, notes, and snippets.

@abkrim
Created August 21, 2023 08:47
Show Gist options
  • Save abkrim/1ced692e9f5dd6b99af2c82564c383c9 to your computer and use it in GitHub Desktop.
Save abkrim/1ced692e9f5dd6b99af2c82564c383c9 to your computer and use it in GitHub Desktop.
Solution at problem, with firestoreImport.js en The Vue MasterClass 3 - Lesson 65

There's a problem, as always in this kind of Vue classes, due to the gap between when the course content was created and when it was recorded. Versions change, methods change, and in the end, many times one experiences a kind of frustration due to the disparity. I'm not at the right level of knowledge right now to delve into this mess. Importing data from The Master Class Vue 3 with Firestore is one of these cases. CommonJS versus Default, different versions, different scopes. My solution (which is not entirely correct, given the level of the courses where we're using CommonJS, I believe that's what it's called). Because of this, I had to temporarily modify my package.json for the import, adding "type": "module".

firestoreImport.js

// Imports
import firestoreService from "firestore-export-import";
import firebaseConfig from "./src/config/firebase.js";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);

const __dirname = path.dirname(__filename);
const tempFileName = `${__dirname}/data-temp.json`;

const serviceAccount = JSON.parse(
  fs.readFileSync("./serviceAccount.json", "utf8")
);
// procedure
(async () => {
  const fileContents = fs.readFileSync(`${__dirname}/src/data.json`, "utf8");
  const data = JSON.parse(fileContents);
  const transformed = transformDataForFirestore(data);
  fs.writeFileSync(tempFileName, JSON.stringify(transformed));
  await jsonToFirestore();
  fs.unlinkSync(tempFileName);
})();

// Helper Functions
// -------------------------------------

// JSON To Firestore
async function jsonToFirestore() {
  try {
    console.log("Initialzing Firebase");
    await firestoreService.initializeFirebaseApp(
      serviceAccount,
      firebaseConfig.databaseURL
    );
    console.log("Firebase Initialized");
    await firestoreService.restore(tempFileName);
    console.log("Upload Success");
  } catch (error) {
    console.log(error);
  }
}

// In order to preserve ids in data.json
// as ids in firestore
// must use keyed object (id being the key) instead of array of records
function transformDataForFirestore(data) {
  const collections = data;
  delete collections.stats;
  const collectionsById = {};
  Object.keys(collections).forEach((collectionKey) => {
    collectionsById[collectionKey] = {};
    const collection = collections[collectionKey];
    collection.forEach((record) => {
      collectionsById[collectionKey][record.id] = record;
      delete collectionsById[collectionKey][record.id].id;
    });
  });
  return collectionsById;
}

firebase.js

The data is fictional, and the databaseURL was added, which you should obtain by following Installation & Setup in JavaScript.

import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";


const config = {
  apiKey: 'AIzaSyBvWvfBAPIAPIKEYKEY',
  authDomain: 'vue-school-forum-XXXXXX.firebaseapp.com',
  projectId: 'vue-school-forum-XXXXX',
  storageBucket: 'vue-school-forum-dXXXX.appspot.com',
  messagingSenderId: '407250000083',
  appId: '1:407255686283:web:07c996faasdasdasads88e',
  databaseURL: 'https://vue-school-forum-d1d86.europe-west1.firebasedatabase.app'
}


const app = initializeApp(config);
const db = getFirestore(app);
export default db;

Package.json

Just in case, I'll leave it here.

{
  "name": "vueschool-forum",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "db:seed": "firebase firestore:delete --all-collections --yes && node firestoreImport"
  },
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^1.2.35",
    "@fortawesome/free-solid-svg-icons": "^5.15.3",
    "@fortawesome/vue-fontawesome": "^3.0.0-3",
    "@hennge/vue3-pagination": "^1.0.17",
    "@vee-validate/i18n": "^4.4.7",
    "@vee-validate/rules": "^4.4.7",
    "@vueuse/head": "^0.6.0",
    "core-js": "^3.28.0",
    "dayjs": "^1.10.4",
    "firebase": "^10.2.0",
    "lodash": "^4.17.21",
    "nprogress": "^0.2.0",
    "vee-validate": "^4.4.11",
    "vue": "^3.0.0",
    "vue-final-modal": "^3.4.2",
    "vue-router": "^4.0.3",
    "vuex": "^4.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.21.0",
    "@babel/eslint-parser": "^7.19.1",
    "@vue/cli-plugin-babel": "^5.0.8",
    "@vue/cli-plugin-eslint": "^5.0.8",
    "@vue/cli-service": "^5.0.8",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/eslint-config-standard": "^5.1.2",
    "babel-eslint": "^10.1.0",
    "eslint": "^8.29.0",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^9.9.0",
    "firestore-export-import": "^1.3.6",
    "vue-cli-plugin-webpack-bundle-analyzer": "~4.0.0"
  },
  "type": "module",
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}
@hazemhamdyabdo
Copy link

when I write node ./firestoreImport.js in terminal show this error SyntaxError: Cannot use import statement outside a module how can i solve that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment