80
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-04-16

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:

80
77
10

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
80
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?