> For the complete documentation index, see [llms.txt](https://ja.docs.monaca.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ja.docs.monaca.io/migration-guide/nifcloud/datastore/data-migration-script.md).

# データ移行スクリプト実行手順

ニフクラmobile backendからFirebase Firestoreにデータを移行するためのスクリプトを実行する手順を説明します。

{% hint style="warning" %}
本スクリプトは、Firestoreのコレクションにデータを追加します。必ずテスト環境でお試しの上、本番環境へのデータインポートをお願いします。
{% endhint %}

## **必要条件**

* **Node.jsがインストールされた環境:** \
  このプロジェクトを進めるためには、Node.jsがインストールされている環境が必須です。手順1では、Node.jsのインストールリンクを案内しています。
* **Firebase Admin SDKの設定ファイル:** \
  Firebase Admin SDKを使用するためには、設定ファイルが必要です。手順2では、Firebase Admin SDKの設定ファイルの準備方法を案内します。

## **手順**

### **1. 環境準備**

* Node.jsがまだインストールされていない場合は、[Node.js公式サイト](https://nodejs.org/)からインストールしてください。

### **2. Firebase Admin SDKの設定**

* Firebaseプロジェクトにアクセスし、Firebase Admin SDKの設定ファイル（firebase-adminsdk.json）をダウンロードします。
* ダウンロードしたファイルを、後で作成するスクリプトファイルと同じディレクトリに配置します。

{% embed url="<https://youtu.be/Y-rH4qK00xM>" %}
Firebase Admin SDKの作成
{% endembed %}

### **3. データファイルの準備**

* ニフクラmobile backendからエクスポートしたJSON形式のデータファイル（例：**`import.json`**）を用意します。
* このファイルもスクリプトファイルと同じディレクトリに配置します。

### **4. スクリプトの作成**

* 以下のスクリプト&#x3092;**`migrate.js`**&#x3068;して新しいファイルとして保存します。

```javascript
const admin = require('firebase-admin');
const fs = require('fs');

// Firebaseの設定 ※ダウンロードした Firebase Admin SDKの設定ファイル名に変更してください
const serviceAccount = require('./serviceAccountKey.json');
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

const db = admin.firestore();

// JSONファイルの読み込み (※ ファイル名は、import.jsonにしています。)
const data = JSON.parse(fs.readFileSync('import.json', 'utf8'));

// Firestoreにデータをインポート
data.results.forEach(async (item) => {
  // aclフィールドを削除
  delete item.acl;

  // createDateとupdateDateを文字列形式に変換
  if (item.createDate && item.createDate.iso) {
    item.createDate = item.createDate.iso;
  }
  if (item.updateDate && item.updateDate.iso) {
    item.updateDate = item.updateDate.iso;
  }
  
  // ※コレクション名は任意の名前に変更してください
  await db.collection('yourCollectionName').doc(item.objectId).set(item)
    .then(() => console.log(`Document ${item.objectId} successfully written!`))
    .catch((error) => console.error("Error writing document: ", error));
});
```

### **5. 必要なパッケージのインストール**

* コマンドラインまたはターミナルを開き、スクリプトファイルが保存されているディレクトリに移動します。
* 次のコマンドを実行して、必要なパッケージをインストールします。

  ```
  npm install firebase-admin
  ```

### **6. スクリプトの実行**

* 以下のコマンドを実行してスクリプトを実行します。

  ```
  node migrate.js
  ```
* スクリプトが正常に実行されると、コンソールに成功メッセージが表示されます。

### 7. Firebaseコンソールでの確認

スクリプトの実行結果をFirebaseコンソール上で確認してください。インポートが成功すると、Firebaseコンソール上で次のように確認できます。

{% hint style="info" %}
移行スクリプトでは、ニフクラmobile backendのユニークなIDである「objectId」を、Firestoreコレクションのフィールドとして「objectId」という名前でインポートしています。これにより、ニフクラmobile backendで使用されているデータの識別子をFirestoreでも同様に利用できるようになります。
{% endhint %}

<figure><img src="/files/ane4RcgJ3D3I2TMSJGnf" alt=""><figcaption><p>インポートされたデータの例</p></figcaption></figure>

#### **注意点**

* ニフクラ mobile backendからエクスポートしたファイルは、上記のスクリプトで&#x306F;**`import.json`**&#x3068;いうファイル名で扱っています。
* `'`**`yourCollectionName`**`'`は、Firebase Firestore内で使用したいコレクションの名前に置き換えてください。
* スクリプト実行中にエラーが発生した場合は、エラーメッセージを確認し、適切に対処してください。

***

## 移行スクリプトで実施しているデータ変換について

スクリプトでは、ニフクラmobile backendからエクスポートしたデータをFirestoreに適した形式に変換しています。具体的に行われている変換処理は以下の通りです。

### 1. `acl`フィールドの削除

ニフクラmobile backendのデータに含まれる`acl`（Access Control List）フィールドは、データのアクセス権限を定義しています。Firestoreには異なる権限管理システムがあるため、この`acl`フィールドはFirestoreに移行する際に不要となります。そのため、このフィールドを各データ項目から削除しています。

```javascript
delete item.acl;
```

### 2. `createDate`と`updateDate`の変換

ニフクラmobile backendのデータでは、`createDate`と`updateDate`はオブジェクト形式で、`iso`プロパティに日付の文字列が格納されています。例えば、以下のような構造です。

```json
"createDate": {
  "iso": "2023-12-18T05:04:58.950Z"
}
```

Firestoreでは、日付をより直接的な形式（単なる文字列）で保存するのが一般的です。そのため、スクリプトではこれらのフィールドを文字列に変換しています。具体的には、`iso`プロパティの値を直接`createDate`と`updateDate`フィールドに設定しています。

```javascript
if (item.createDate && item.createDate.iso) {
  item.createDate = item.createDate.iso;
}
if (item.updateDate && item.updateDate.iso) {
  item.updateDate = item.updateDate.iso;
}
```
