Help us understand the problem. What is going on with this article?

FirebaseでTwitterログインを利用し最速で「いいね」機能をつくる 〜究極の選択をつくるサービスをリリースした話〜

More than 1 year has passed since last update.

TL;DR(要約)

自己紹介

個人的なプロジェクト「毎月サービスリリースで技術もノウハウもうっはうは祭り:fire:」をしています、ミツダマ(@mitudama)です。
1月の時間割メーカー、2月の俳句メーカーに引き続き3月は究極の選択メーカーをリリースしました!
今回はTwitterログインについて勉強していいね機能、アンケート機能を実現しましたのでメモします!

作ったサービス

何で作ったか

・ユーザーを識別してイイねやアンケート機能をもつサービスをつくりたい
・どうやらfirebaseを使えば簡単にTwitterログインを使えるらしい
・作っちゃえ
・作った

使った技術と参考サイト

基本的に時間割メーカー俳句メーカーで使った技術と同じですが、そのほかで新たに導入した技術は以下になります。

  • Firebase
    • Authentication: Twitter Loginが利用できる。簡単。

screenshot-2019-03-05-233315.png

  • Twitter API
    • 皆さんご存知ツイッター情報を利用するためのAPI。

image.png

Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ

最速でいいね機能を作るチュートリアル

Vueのコーディング

以下コピペでOKです!

index.vue
<template>
  <div class="container_area">
    <div>
        <button 
          @click="logIn">ログイン</button>
        <button 
          @click="logOut">ログアウト</button>
      </div>
      <div class="btn_area">
        <div>
          <button 
            v-if="!likedFlg"
            @click="addLikeUsr()"
            class="btn like-btn">
              <i class="fa fa-fw fa-thumbs-up"></i> 
          </button>
          <button 
            v-if="likedFlg"
            @click="delLikeUsr()"
            class="btn like-btn">
              <i class="fa fa-fw fa-check"></i> 
          </button>
          <span class="like-count">{{likeSum}}よかね</span>
        </div>
      </div>
  </div>
</template>

<script>
import firebase from 'firebase'
import 'firebase/firestore';
var config = {
  apiKey: "",
  authDomain: "",
  databaseURL: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: ""
};
if (!firebase.apps.length) {
    firebase.initializeApp(config);
}
var db = firebase.firestore();
export default {
  components: {
  },
  data() {
    return {
      likeSum: 0,
      likedFlg: false,
      loginUser:null,
      documentId: ""  //FirestoreのdocumentIdを指定
    };
  },
  created() {
    firebase.auth().onAuthStateChanged((user)=> {
      if (user) {
        this.loginUser = user;
      } else {
      }
    });
    var docRef = db.collection("posts").doc(this.documentId);
    this.getLikeUserByDocumentId(docRef)
  },
  methods: {
    logIn() {
      var provider = new firebase.auth.TwitterAuthProvider();
      firebase.auth().signInWithRedirect(provider);
    },
    logOut(){
      firebase.auth().signOut().then(function() {
        // Sign-out successful.
        console.log("signOut")
      }).catch(function(error) {
        // An error happened.
      });
    },
    addLikeUsr(){
      var docRef = db.collection("posts").doc(this.documentId);
      docRef.update({
            "like_users": firebase.firestore.FieldValue.arrayUnion(this.loginUser.uid),
        })
      this.getLikeUserByDocumentId(docRef)
    },
    delLikeUsr(){
      var docRef = db.collection("posts").doc(this.documentId);
      docRef.update({
            "like_users": firebase.firestore.FieldValue.arrayRemove(this.loginUser.uid),
        })
      this.getLikeUserByDocumentId(docRef)
    },
    getLikeUserByDocumentId(docRef){
      // ドキュメント取得
      docRef.get().then(doc => {
          if (doc.exists) {
            this.posts = doc.data();
            this.likeSum = this.posts.like_users.length
            // すでにいいねされていないか確認用フラグ
            this.likedFlg = this.posts.like_users.includes(this.loginUser.uid)
          } else {
              console.log("No such document!");
          }
      }).catch(function(error) {
          console.log("Error getting document:", error);
      });
    },
  }
}
</script>

<style>
.container_area {
  width: 300px;
  margin-top: 50px;
  padding: 20px;
  margin-right: auto;
  margin-left: auto;
  text-align: center;
}
.btn_area{
  margin-top: 20px;
}
.like-btn{
  font-size: 20px;
  color: #55c500;
  background-color: #fff;
  border: 2px solid #55c500;
  border-radius: 90%;
  outline: none;
}
.like-count{
  color: #55c500;
}
.border-double{
  border:double 10px dimgray;
}
</style>




以下の画面になればOKです。

image.png

Twitterログイン・ログアウト

(公式)JavaScript で Twitter を使用して認証する

logIn() {
  var provider = new firebase.auth.TwitterAuthProvider();
  firebase.auth().signInWithRedirect(provider);
},
logOut(){
  firebase.auth().signOut().then(function() {
    // Sign-out successful.
    console.log("signOut")
  }).catch(function(error) {
    // An error happened.
  });
},

これだけでログイン時はツイッター画面へ遷移し、連携&リダイレクトまでしてくれるのです。
image.png

現在ログインしているユーザーを取得する

Firebase でユーザーを管理する

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
    this.loginUser = user;
  } else {
    // No user is signed in.
  }
});

これをcreatedに記載すればページが読み込まれたタイミングでユーザー情報を取得できます。

いいね機能実装

まずはコレクションを作成。

image.png

like_usersフィールド(配列)を用意して「いいね」を押してくれたユーザーのIDをポンポンと追加する形でいいね機能を実装していきます。
その際、配列の追加にはarrayUnionを使います。

firestore で配列の検索・追加・削除がサポートされたので試してみた

配列の追加

docRef.update({
    "like_users": firebase.firestore.FieldValue.arrayUnion(user_id),
})

配列の削除

docRef.update({
    "like_users": firebase.firestore.FieldValue.arrayRemove(user_id),
})

あとは追加・削除ボタンが押される度にこれらを実行するだけ。
ちなみに数のカウントは変数を用意して配列数を代入してます。

        this.likeSum = this.posts.like_users.length

image.png

これでいいね機能が実装できました!
そしていいね機能さえできればアンケート機能も簡単に実装できます。
興味のある方はoption1_usersフィールドとoption2_usersフィールドをこねこねして作ってみてください。

感想

という訳であっという間にいいね機能をもつサービスができてしまいました。

それにしてもFirebaseはやっぱすごいですね。
ログイン処理つくるのめんどくせぇなと思ってたのが嘘のようです。
もうツイッターログインを利用しないサービスなんて考えられません。ほんとありがとうございました。

終わりに

ぜひ究極の選択メーカーで遊んで見てください!

こんな投稿待ってます!
image.png

あとは技術系ではないのでCrieitにて究極の選択メーカーの裏話エピソードを書いてます!
月500円の不労所得を得るためにWEBサービスを開発した話 〜 もうやめて!とっくに個人開発者のライフはゼロよ! 〜

Twitterもフォローよろしくです!:relaxed:

ではまた来月〜:wave:

admin-guild
「Webサービスの運営に必要なあらゆる知見」を共有できる場として作られた、運営者のためのコミュニティです。
https://admin-guild.slack.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away