Chrome拡張とFirebaseで作るチャットアプリ

We Are JavaScripters! @23rd

くにさだ
@92thunder

テックタッチ株式会社にて
フロントエンジニアとして
自社サービスを開発中

Browser Chat

同じサイトを閲覧している

ユーザとチャットできるようにするChrome拡張機能

きっかけ

  • 最近仕事で開発しているChrome拡張機能
    の知識を使って何か作りたい

     
  • 当然のようにブラウザにログインする時代になっているし面白いことできそう
     
  • はてなブックマークのリアルタイム版みたいなのがあれば需要ありそう

概要

  1. Chrome拡張がVueアプリを
    ページに差し込む
     
  2. Firebase Authenticationで
    Google, Twitterログイン
     
  3. Firebase Cloud Firestoreで
    簡単チャット開発

Chrome拡張機能の作り方

Chrome拡張の基本

content_script 閲覧ページ上で
動作するJS
 
background タブに依存せず
裏で動作するJS
今回は認証ポップアップ呼び出しに使用
page_action アイコンクリックで表示されるhtmlファイル
 
options_page アイコン右クリック→オプション

 

Webpack設定

module.exports = {
  // evalが使えないのでdevtool設定を変更する
  devtool: "cheap-module-source-map",
  entry: {
  // 閲覧してるページ上にVueアプリを差し込む
    main: "./src/main.ts",
  // Firebase Authenticationを動かすために必要
    background: "./src/background.ts"
  },
  output: {
    path: path.resolve("dist"),
    filename: "[name].js"
  },
  .......
}

Vueアプリ差し込み

import Vue from "vue";
import App from "./App.vue";

// 見ているページのbodyにエレメント追加
const appId = "bc-app";
const appDiv = document.createElement("div");
appDiv.id = appId;
document.body.appendChild(appDiv);

new Vue({
  render: h => h(App)
}).$mount(`#${appId}`);

// あとはいつも通りVueでUIを作っていく

Firebase Authenticationで簡単にユーザ認証

Firebase Authentication

  • Google, Facebook, Twitter, Github, メールアドレス, 電話番号などでの認証を簡単に実装できる
     
  • 今回はGoogle, Twitterアカウントで
    ログイン、ユーザ情報取得を行う

Firebase Consoleで設定

認証ポップアップ作成

firebase.auth()
    .signInWithPopup(new firebase.auth.GoogleAuthProvider())
    .then(result => {
      var token = result.credential.accessToken
      // 取得したuser情報をchrome.storage.localに保存する
      // 丸ごと保存しようとするとデータが大きすぎて
      // Chrome拡張がフリーズするので変換が必要
      var user = result.user
    })

Firestoreを使って
爆速でチャットを作る

Firebase Firestore

  • NoSQLのデータストア
     
  • データの変更を同期してくれる機能が便利で
    爆速でチャットを実装できる

FirestoreとVueのデータ同期

  mounted() {
    this.unsubscribe = firebase.firestore()
      .collection("channels")
      .doc(location.host)
      .collection("messages")
      .orderBy("date")
      .onSnapshot(snapshot => {
        let messages: any[] = []
        snapshot.docs.forEach(doc => {
          messages.push({
            id: doc.id,
            ...doc.data()
          })
        })
        this.messages = messages
     })
}

メッセージ送信

  db.collection("channels")
    .doc(location.host)
    .collection("messages")
    .add({
      text: this.text,
      date: Date.now(),
      userPhotoURL: this.user.photoURL,
      userName: this.user.displayName,
      uid: this.user.uid
    })

まとめ

  • Firebaseを使って短時間で面白いChrome拡張機能を作ることができた
     
  • Chrome拡張機能でブラウジングを
    もっと楽しい体験にできる!😁
     
  • 闇の少ないサービスに育てていきたい😎

We are hiring!

テックタッチ株式会社では
ゼロからBtoB SaaSを
育てる仲間を募集中です!