LoginSignup
5
1

More than 3 years have passed since last update.

FirebaseUiでユーザー作成時に、認証プロバイダのサムネイルを引き継ぐ方法

Posted at

Firebase UI

FirebaseにはFirebaseUIという、ユーザー認証を素晴らしく楽にさせてくれる素晴らしいシステムがあります。

少しコードを書くだけで、googleアカウントはもちろんfacebookやtwitter、github、SMS認証、メール認証なども網羅しているすごいやつです。


(※firebase.google.comより引用)

本記事では、Firebase UI を利用してユーザー登録を行なった際に、利用したプロバイダに登録している画像を取得・保存する実装について書いていきます。

概要

Functionsにて、authenticateでユーザーが作成される事をフックして、Firestoreにユーザー情報を取得すると同時に、Storageに認証プロバイダのユーザーアイコンを保存するといった仕組みを撮りました。

実装

必要なモジュールたちをインポートします。

functions/index.js
const functions = require('firebase-functions')
const admin = require('firebase-admin')
const axios = require('axios') // いつもの子
const path = require('path') //////
const os = require('os') // ここら辺を使って画像取得、送信準備をおこないます。
const fs = require('fs') ///////
const STORAGE_BUCKET = 'XXXXX-YYYYYYYY-ZZZZZZZ' // 自分のfirebaseアプリ名が含まれた?、storageのバケット名です。

admin.initializeApp()
const db = admin.firestore()

ユーザの作成イベントをフックしてfirestoreにデータを保存する処理です。storageへの保存は非同期でおこないました。

functions/index.js
exports.userCreated = functions.auth.user().onCreate(async (user) => {
  const encodedPath = encodeURIComponent(`/images/users/thumbnails/${user.uid}.jpg`)
  uploadThumbnail(user)

  db.collection('users').doc(user.uid).set({
    name: user.displayName,
    // getSignedUrlを利用するのが本来のやり方のようですが、いまいちうまくいかないので、非公式ではありますが
    // 色々なサイトに書かれている方法でstorage画像へのパスを保存しました。
    thumbnail: `https://firebasestorage.googleapis.com/v0/b/${STORAGE_BUCKET}/o${encodedPath}?alt=media`,
    updated_at: new Date(),
    created_at: new Date(),
  })

user.photoURLの中にプロバイダのユーザーアイコンが入っているため、そこからごにょごにょしてからstorageに送信する処理です。
(arraybufferのままstorageに送れたかもです。知ってたらおしえてください :bow:)

functions/index.js
async function uploadThumbnail (user) {
  const bucket = admin.storage().bucket()
  const tmpFile = path.join(os.tmpdir(), `tmp_${user.uid}.jpg`)
  const res = await axios.get(user.photoURL, {responseType: 'arraybuffer'})
  fs.writeFileSync(tmpFile, new Buffer.from(res.data), 'binary')

  const filePath = `images/users/thumbnails/${user.uid}.jpg`
  bucket.upload(tmpFile, { destination: filePath }).then(res => {
    return 'success'
  }).catch(e => {
    console.log(`[ERROR]: at uploadThumbnail --- ${e}`)
  })
  return ''
}

これでユーザーのアイコンがプロバイダから引き継げました!!
関係ないですが、authのフックをするのが至極簡単で本当に素晴らしきですね。。。

終わり!

ユーザー認証の際に認証に利用したプロバイダに登録してあるアイコンを引き継ぐ方法でした!
著作権とかあるとおもうので、引き継ぐか否かとかはユーザーに確認取った方がいい、かも、、、?

ありがとうございました!

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1