【Next.js】Firestoreのデータを削除する

f:id:nekorokkekun:20190923093024p:plain:w1000
今回はNext.jsからFirebase Cloud Firestoreのデータを削除する方法について解説していきます。

以下の記事を前提にしています。
nekorokkekun.hatenablog.com
nekorokkekun.hatenablog.com

コードの全体像

まずは今回のコードの全体像を見ていきましょう。

import { db } from '../lib/db';
import React from 'react'

 export default class Posts extends React.Component {
  static async getInitialProps() {
    let result = await new Promise((resolve, reject) => {
      db.collection('posts')
      .get()
      .then(snapshot => {
        let data = []
        snapshot.forEach((doc) => {
          data.push(
            Object.assign({
              id: doc.id
            }, doc.data())
          )
        })
        resolve(data)
      }).catch(error => {
        reject([])
      })
    })
    return {posts: result}
  }

  handleDelete = (id) => {
    db.collection('posts')
    .doc(id)
    .delete()
    .then(function() {
      console.log("Document successfully deleted!");
    }).catch(function(error) {
      console.error("Error removing document: ", error);
    });
  }

  render() {
    const posts = this.props.posts
    return (
        <React.Fragment>
                {posts.map(post =>
                    <div className="post" key={post.id}>
                        <h2>
                            {post.title}
                        </h2>
                        <p>
                            {post.body}
                        </p>
                        <button onClick={this.handleDelete.bind(this, post.id)}>削除</button>
                    </div>
                    )}
            <style jsx>{`
            .post {
                width: 40%;
                border: 1px solid black;
                background-color: gray;
                margin-bottom: 10px;
            }
            `}</style>
        </React.Fragment>
    );
  }
}

一意のidを取得する

削除する際に「どのデータを削除するのか」を識別するための一意のidを取得する必要があります。

こちらの記事で述べている通り、Firestoreにデータを登録する際、setで任意のidを設定するか、addで自動的に一意のidを作成しているかと思います。

そのidを特定するためには以下のような記述が必要です。

                {posts.map(post =>
                    <div className="post" key={post.id}>
                        <h2>
                            {post.title}
                        </h2>
                        <p>
                            {post.body}
                        </p>
                        <button onClick={this.handleDelete.bind(this, post.id)}>削除</button>
                    </div>
                    )}

map関数で取得したFirestoreの全データを1つずつ展開しています。

中でも以下の記述に着目してほしく、

<button onClick={this.handleDelete.bind(this, post.id)}>削除</button>

後ほど解説するhandleDeleteというイベントにbindしてpost.idを付随させています。
「post.id」が一意のidということになり、それをイベントにbindさせているということです。

また、onClickにhandleDeleteイベントを指定することによって、クリックすると該当のidのデータを削除する、という運びになります。

削除イベントの作成

  handleDelete = (id) => {
    db.collection('posts')
    .doc(id)
    .delete()
    .then(function() {
      console.log("Document successfully deleted!");
    }).catch(function(error) {
      console.error("Error removing document: ", error);
    });
  }

こちらが指定したidのデータを削除するためのイベントです。
delete関数で指定したidを持つデータが削除されるようになっています。

詳しくは公式ドキュメントを参照してください。

これで該当のデータを削除ボタンで削除できるようになりました!