FirebaseにユーザーをCSVインポートする方法
現時点(2019年5月時点)でFirebaseの管理画面からユーザーを一括でインポートする方法がありません。npm を使ってFirebase CLI をダウンロードするか、ユーザーをインポートする用のアプリケーションを作る必要があります。
今回は両方の方法をご紹介します。
まずは簡易的なアプリケーションを作ってユーザーをインポートする方法からご紹介します。既に「FirestoreにCSVをインポートする方法 」をご覧になった方は「2-2.インポートの流れ」まで読み飛ばしていただいても問題ありません。
1. 準備する
1-1. モジュールのインポートと初期設定
ユーザーインポート用のアプリケーションにはNode.jsを使います。
それではアプリケーションを作るディレクトリへ移動し、以下のモジュールをターミナルからインストールしましょう。
1 |
npm install csv-parse firebase-admin fs |
必要なモジュールをインストールしたら、package.jsonを作りましょう。
1 |
npm init |
package.jsonに記載する情報を聞かれるので、順に答えて行ってください。以下、参考です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "name": "firestoreimportexport", "version": "1.0.0", "description": "supports csv import and export for firestore", "main": "index.js", "dependencies": { "csv-parse": "^3.2.0", "firebase-admin": "^6.1.0", "fs": "^0.0.1-security" }, "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Orange", "license": "ISC" } |
1-2. Firebase ServiceAccountの用意
Firebase Admin SDKを使うには、ServiceAccountのjsonファイルが必要になります。ServiceAccountファイルは、Firebaseの管理画面の「プロジェクトの設定」>「サービスアカウント」からダウンロード出来ます。ダウンロードしたファイルをさっき作成したpackage.jsonと同じ階層に入れてください。
2. コーディング
2-1. Adminの初期化
準備は整いましたので、index.jsのファイルを作成し、firebase adminの初期化を行いましょう。初期化のコードはFirebase 管理画面の「プロジェクト設定」>「サービスアカウント」のAdmin SDK構成スニペットからコピペ出来ます。
1 2 3 4 5 6 7 8 |
var admin = require("firebase-admin"); var serviceAccount = require("path/to/serviceAccountKey.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://[projectID].firebaseio.com" }); |
2-2. インポートの流れ
CSVデータをインポートする流れとしては:
- CSVファイルをパースする
- パースしたCSVデータを forEachで回して空の配列の中にkey-value形式で入れていく。
- トランザクションを作成し、インポートする。
それではindex.jsに以下を追加してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
const db = admin.firestore() const fs = require('fs') const csvSync = require('csv-parse/lib/sync') const file = 'hoge.csv' //インポートしたいcsvファイルをindex.jsと同じ階層に入れてください let data = fs.readFileSync(file) //csvファイルの読み込み let responses = csvSync(data) //parse csv let objects = [] //この配列の中にパースしたcsvの中身をkey-value形式で入れていく。 //================================================// // 一回のインポートで1000件まで! // //===============================================// responses.shift(); //ヘッダもインポートされてしまうから、一番最初のelementは削除します。 responses.forEach(function(response) { objects.push({ uid: response[0], email: response[1], passwordHash: Buffer.from(response[2]), }) }, this) |
配列の中に入れるデータはサポートされているプロパティの組み合わせになります。
Firebase プロジェクトのユーザーには以下のプロパティ がサポートされています:
列番号 | フィールドの説明 | フィールド タイプ | コメント |
---|---|---|---|
1 | UID | 文字列 | 必須です。この ID は、Firebase プロジェクト内のすべてのアカウントで一意である必要があります。すでに存在する UID を持つアカウントをインポートした場合は、アカウントが上書きされます。 |
2 | メール | 文字列 | 省略可 |
3 | 検証済みのメール | ブール値 | 省略可 |
4 | パスワード ハッシュ | 文字列 | 省略可。base64 でエンコードされた文字列。このフィールドを使用するには、呼び出し側に編集者または所有者の役割が必要です。 |
5 | パスワード Salt | 文字列 | 省略可。base64 でエンコードされた文字列。このフィールドを使用するには、呼び出し側に編集者または所有者の役割が必要です。 |
6 | 名前 | 文字列 | 省略可 |
7 | 写真 URL | 文字列 | 省略可 |
8 | Google ID | 文字列 | 省略可 |
9 | Google メール | 文字列 | 省略可 |
10 | Google 表示名 | 文字列 | 省略可 |
11 | Google 写真 URL | 文字列 | 省略可 |
12 | Facebook ID | 文字列 | 省略可 |
13 | Facebook メール | 文字列 | 省略可 |
14 | Facebook 表示名 | 文字列 | 省略可 |
15 | Facebook 写真 URL | 文字列 | 省略可 |
16 | Twitter ID | 文字列 | 省略可 |
17 | Twitter メール | 文字列 | 省略可 |
18 | Twitter 表示名 | 文字列 | 省略可 |
19 | Twitter 写真 URL | 文字列 | 省略可 |
20 | GitHub ID | 文字列 | 省略可 |
21 | GitHub メール | 文字列 | 省略可 |
22 | GitHub 表示名 | 文字列 | 省略可 |
23 | GitHub 写真 URL | 文字列 | 省略可 |
24 | ユーザーの作成時間 | Long 型 | 省略可。Epoch Unix タイムスタンプ(ミリ秒単位) |
25 | 最終ログイン時間 | Long 型 | 省略可。Epoch Unix タイムスタンプ(ミリ秒単位) |
26 | 電話番号 | 文字列 | 省略可。 |
なお、firebaseの公式ドキュメント に以下のように記載されています:
1 回の API 呼び出しで最大 1,000 人のユーザーをインポートできます。このオペレーションは高速処理を目的として改善されていて、uid、email、phoneNumber などの一意の識別子の重複はチェックされないことに注意してください。既存の uid と衝突するユーザーをインポートすると、既存のユーザーが置き換えられます。他のフィールドが重複している(たとえば、email)ユーザーをインポートすると、追加のユーザーが同じ値になります。したがって、この API を使用する場合は、一意のフィールドが重複しないように気をつける必要があります。
重複するuidがある場合、データが上書きされますので十分にご注意ください。
2-3.トランザクション
次に、配列に入れたユーザーデータを一括インポートしていきます。
index.jsに以下を追加してください。
1 2 3 4 5 6 7 8 9 10 11 12 |
return admin.auth().importUsers(objects, { hash: { algorithm: 'BCRYPT' } }).then(function(results) { results.errors.forEach(function(indexedError) { console.log('Error importing user ' + indexedError.index); }); console.log('done') }).catch(function(error) { console.log('Error importing users:', error); }); |
上から読み砕いていきましょう。
1 2 3 4 5 |
return admin.auth().importUsers(objects, { hash: { algorithm: 'BCRYPT' } }) |
このハッシュアルゴリズムにはパスワードハッシュに使ったアルゴリズムを指定します。BCRYPTの他にも、HMAC、MD5、SHA、PBKDFやSCRYPTなどがございます。それぞれのアルゴリズムによってはハッシュパラメータが異なりますので、詳しくはこちらのページ をご確認ください。
パスワードハッシュが必要ない場合は、ハッシュオプションの指定は必要ありません。
インポートが終わったら、その結果が返ってきます。
1 2 3 4 5 6 7 8 |
.then(function(results) { results.errors.forEach(function(indexedError) { console.log('Error importing user ' + indexedError.index); }); console.log('done') }).catch(function(error) { console.log('Error importing users:', error); }); |
エラーがある場合はインデックス値と共に「Error importing user」がコンソールで表示されます。何事もなく成功した場合はコンソールに「done」と表示されます。
2-4. SNS連携ユーザー
SNSログインなどで作成されたユーザーアカウントをインポートするには該当部分を以下のように変えてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
responses.forEach(function(response) { objects.push({ uid: response[0], email: response[1], passwordHash: Buffer.from(response[2]), providerData: [{ providerId: response[3], uid: response[4] }] }) }, this) |
providerDataのプロパティが追加されました。
providerIdのフィールドはgoogle.com、facebook.com、github.com、twitter.com のいずれかの値にする必要があります。
providerData[uid]にはprovider-uidを入れてください。
また、最近ではSNSログインする際に連携アプリがemail情報を取得する事を拒否する事も可能になっています。そのため、emailプロパティの値がnullになっている場合あります。emailプロパティがnullになっているとインポートが失敗するのでemail情報を取得出来なかったユーザー達は別のcsvにまとめて、
1 |
email: response[1] |
の部分をコメントアウトしてからもう一度インポートすると楽かもしれません。
index.jsは最終的には以下のようになっているはずです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
var admin = require("firebase-admin"); var serviceAccount = require("path/to/serviceAccountKey.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://[projectID].firebaseio.com" }); const db = admin.firestore() const fs = require('fs') const csvSync = require('csv-parse/lib/sync') const file = 'hoge.csv' //インポートしたいcsvファイルをindex.jsと同じ階層に入れてください let data = fs.readFileSync(file) //csvファイルの読み込み let responses = csvSync(data) //parse csv let objects = [] //この配列の中にパースしたcsvの中身をkey-value形式で入れていく。 //================================================// // 一回のインポートで1000件まで! // //===============================================// responses.shift(); //ヘッダもインポートされてしまうから、一番最初のelementは削除します。 responses.forEach(function(response) { objects.push({ uid: response[0], email: response[1], passwordHash: Buffer.from(response[2]), providerData: [{ providerId: response[3], uid: response[4] }] }) }, this) return admin.auth().importUsers(objects, { hash: { algorithm: 'BCRYPT' } }).then(function(results) { results.errors.forEach(function(indexedError) { console.log('Error importing user ' + indexedError.index); }); console.log('done') }).catch(function(error) { console.log('Error importing users:', error); }); |
3.Firebase CLIを使ってユーザーインポート
個人的にはFirebase CLIを使ってユーザーインポートする事をおすすめします。この方法の方が圧倒的に楽です。
例えば非プログラマーの方々も簡単にクライアントからユーザーインポート出来るようにしたい場合は上記のようにアプリケーションを作っても良いかもしれません。その場合はクライアント側の作成はもちろん、ログインや諸々のセキュリティも考慮しないといけなくなると思いますが・・
それはさておき、Firebase CLIを使ってユーザーをインポートする方法を書いていきます。
まずはnpmを使ってFirebase CLIをインストールします。
1 |
npm install -g firebase-tools |
インストールが終わったら:
- インポートしたいcsvがあるディレクトリに移動します。
-
ターミナルでfirebase loginと入力します。
*そうすると、chromeが開くか、ログイン画面のURLがターミナルに表示されます。
- Firebaseプロジェクトの権限を持つユーザーアカウントでログインします。
- ログインしたら、コンソールで以下を入力します。
1 |
firebase auth:import -P projectID account_file --format=file_format |
firebase auth:import -P <firebaseプロジェクトID> user.csv
*プロジェクトIDはFirebaseの管理画面 > 「プロジェクトの設定」からご確認いただけます。
Imported successfully.
と表示されたら成功です。
ちなみに、csvの中にヘッダーが入っているとインポートエラーが起きますのでご注意ください。csvの中身はユーザーデータのみにしてください。
firebase CLIからログアウトするには、コンソールで以下を入力してください。
1 |
firebase logout |
おまけ:ユーザーのカスタムフィールドについて
既にお気づきな方もいらっしゃると思いますが、Firebase ユーザーアカウントにはカスタムフィールドがサポートされていません。
ユーザーアカウントに独自の情報(購入アイテムなど)を紐付けたい場合はFirebaseFirestoreなどを利用して自前で実装しないといけません。
例えば、UserCollectionを作り、各ドキュメントのIDがユーザーのuidになっていればわかりやすいかもしれません。
FirestoreのCSVインポートについては、この記事 でご紹介していますのでよろしければご覧ください。
以上、Firebase ユーザーをCSVで一括インポートする方法でした。ユーザーエクスポートの方法もこちらの記事 でご紹介しているので、よろしければ併せてご覧ください。