中安佑一(69)29この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。はじめにモバイルアプリサービス部の中安です。「Firebaseを触ってみるシリーズ」の続きになります。Firestoreでプロフィール機能を作ってみようと思います。書きますが、何かのお役に立てば幸いです。準備さて、この記事はFirebaseプロジェクトの作成は終わっているXcode側ではFirebaseSDKの組み込みなどが終わっているという前提で書いていきます。このあたりがまだという方は、ドキュメントを参照してくださいませ。認証したユーザと絡めてデータベースを扱うので、冒頭で紹介した前回の記事で作った認証機能がすでにアプリに組み込まれていることも前提にしています。Firestoreのウェルカム画面が表示されます。初期準備としてはその中のデータベースの作成ボタンを押して次へ進みます。途中で出てくるダイアログはとりあえずそのままOKでいいと思います。Firestoreへのデータ移行などが必要になるとのことで注意してください。詳しくはドキュメントを参照ください。Firestoreとはどんなデータベースなんだ」ということを復習しておきましょう。ドキュメントには以下のように書かれています。ドキュメント指向データベースです。データベースとは違い、テーブルや行はありません。代わりに、データは「ドキュメント」に格納し、それが「コレクション」にまとめられます。各「ドキュメント」には、一連のキーと値のペアが含まれています。小型のドキュメントの大きなコレクションを格納するために最適化されています。すべてのドキュメントはコレクションに保存する必要があります。ドキュメントには、「サブコレクション」と、ネストされたオブジェクトを格納できます。このどちらにも、文字列などの基本フィールドや、リストなどの複雑なオブジェクトを含めることができます。平たくいうと「クラウドサービス上に大きなデータ保存用のJSONファイルがある」というイメージを持つとわかりやすくなるかもしれません。(厳密には違うかもですが、自分はそれでしっくりきました)。Firestoreの世界ではいくつかの覚えておくべき用語があります。ドキュメントイメージでいうと「レコード」に近いかもしれません。一般的なRDBの世界ではレコードはそのスキーマ(どういうカラムがあるか)が最初に決まっているのに対して、Firestoreはスキーマレスなデータベースなので、1つのドキュメント内のデータはそれぞれ自由なキーと値が入ることになります。このあたりもJSONをイメージして考えると難しくはないかもしれませんね。コレクションイメージでいうと「テーブル」に近いかもしれません。コレクションは複数のドキュメントの入れ物にあたり、ドキュメントは必ずどこかのコレクションに含まれています。ドキュメントの中に更にコレクションを入れることも可能で「サブコレクション」と呼ばれるそうです。ルール「セキュリティルール」ともいいます。コレクション内のドキュメントへのアクセス制限などを詳細かつ直感的に指定することができます。APIのインターフェイスを作るような感覚(ノリ的にはSwagger的な...いや、違うか)で、「どのコレクションの」「どのドキュメントに」「誰が」「どういう条件で」「何ができる」といったことをプログラマブルに書ける点が良いです。構築の段階で躓く時間は短くなるのではと思います。ルールについては後ほどにも書くのですが、さらなる詳細はドキュメントを参照くださいませ。今回は題名の通り「プロフィール機能のあるアプリ」を作ってみます。プロフィール画面を使ってユーザに属性を追加するイメージになります。アプリ側UIプロフィール画面は下図のような見た目にしました。(プロフィールというよりアンケートのような項目になってしまいましたが・・・)簡単な論理名や仕様は図の矢印で示したとおりです。ビューコントローラビューコントローラはProfileViewControllerとして以下のように用意します。以下のような列挙型(enum)も用意しておきます。.cat]}見たままなので説明は割愛です。Firestore側Firestoreのコンソール画面からルールタブを開きます。この画面ではルールの編集ができます。今回は各ユーザのプロフィール情報を格納する場所としてusersというコレクションを使うものとし、それに対するルールを設定していきます。ルールの概要は認証機能でサインインしたユーザが自分のプロフィール情報のみを触ることができるusersコレクションのドキュメントの識別子はユーザのIDとするにしたいと思うので、ここを下記のように編集します。}}基本的な文法このルール設定は下記の予約語を基本的には使うことになります。適用するドキュメントの場所を指します。WebAPIのパスを設定するような感じですね。指定の場所に対して許可するアクセス権限とその条件です。usersというコレクションの中の{userID}という動的なドキュメント識別子に対してのルールであることを示しています。条件指定allow式の中の:の右側を見てみてください。ここでは条件指定をしています。matchステートメントで書かれている{userID}は、任意の変数のようなものです。それを条件文で使用することができます。このIf文では「認証したユーザのIDと等しい識別子のドキュメント」という条件指定をしているわけです。アクセス権限allow式の中の:の左側はアクセスのパーミッションを表します。基本的なCRUDであるcreate、read、update、deleteの権限を指定できます。この例では「認証したユーザは自分のIDと等しい識別子のドキュメントに追加と更新のパーミッションがある」というusersへのルールができあがったことになります。データ保存の実装それでは、準備で作っていた「登録ボタン押下時」のハンドラメソッドに、Firestoreへのデータ保存機能を実装していきます。}}実装としてはざっとこんな感じです。サンプルなのでベタ書きしています。この記事では既に前回の記事で作った認証機能がアプリには備わっているという前提にして話を進めています。最初のAuth.auth().currentUserでログインユーザを取得しておきます。ここから先には進ませないようにしています。項目の値を取得するここは各アプリによって様々だと思うので、深くは書きません。このサンプルでは列挙体の値はそのままDBに渡すことにします。ここでは文字列とブール値を取っていますが、整数や配列などの値も渡すことが可能です。扱えるデータ型についての詳細はドキュメントを参照くださいFirestoreオブジェクトを取得FirestoreオブジェクトはFirestoreクラスのシングルトンとして用意されているのでそれを呼び出します。Firestore.firestore()データのセットコレクションFirestoreオブジェクトはcollection(_:)を使って、コレクションが抽象化された参照オブジェクトを取得できます。今回はusersコレクションに対してアクセスをしたいので下記のような指定をしています。db.collection("users")ドキュメント先述のルールの項でも書いたように今回はユーザIDをドキュメントの識別子として扱うルールに設定しました。ドキュメントを抽象化した参照オブジェクトを取得することができます。Firestoreデータベースに実際にデータを渡すことができます。その完了時にはエラーがあったかどうかのコールバックを受け取ることができます。成功したときの処理}動作確認では、実際にアプリを起動させて、各項目を色々と動かした後に登録ボタンを押してみましょう。コンソールを見てみるとデータが送られ、保存されていることが確認できました。リアルタイムにコンソール画面の値が更新されるのも確認できると思います。今度は別のドキュメントがusersに新規作成されのも確認できると思います。実際にデータのコンソールにusersというコレクションを足したわけでもないのにデータの送信と保存がされたということです。ドキュメントの中身もアプリ側で指定した通りに保存されています。スキーマに合わせたSQL文を書くなどして挿入・更新をするRDB脳でいるとビックリしますね。これがスキーマレスというわけです。usersコレクションにユーザIDが識別子になっているドキュメントが存在しない場合は、ドキュメントが自動的に新規作成されます。存在する場合はそのドキュメントを自動で更新してくれます。updateと指定しているので、このような動きをしてくれるわけです。試しにupdateをルール記述から消してからアプリを動かしてみてください。ドキュメントの新規作成はしてくれますが、更新しようとするとコールバック時にパーミッションエラーが返されるはずです。データ取得の実装さて、登録したプロフィールがデータベースに保存されたので、今度はそれを取得する動作を実装しようと思います。先ほどはcreateとupdateのパーミッションをルールとして与えていました。取得するときはどうでしょうか。プロフィールは「自分にしか見えない情報」というよりは「他のユーザに見せる情報」とも言える気がします。データの追加や更新とは異なり、他ユーザにもリソースの取得権限は与えたほうが良さそうです。readパーミッションはこのように設定することになると思います。画面が表示されるときに、前回登録した内容が初期値として表示されていてほしいところです。各ビュー部品にバインドしていくことにします。}}ドキュメント取得ドキュメントの参照オブジェクトを取得するまでは保存時と大差ありません。取得の際はそこにgetDocument()メソッドを呼び出します。すると、コールバックとして「ドキュメントのスナップショットオブジェクト」と「エラーオブジェクト」が渡されてきます。スナップショットには指定したドキュメントの有無、存在した場合のドキュメントの内容が入っているので、それを使います。データ保存時に渡したディクショナリと同形式でデータが取得ができるので、加工も簡単かと思います。バインドsnapshot.data()で取得したデータを各ビュー部品にバインドしていきます。これによりアプリの表示とデータベースの内容が同期したといえるでしょう。ディクショナリからデータオブジェクトを作成するほうがソースコード的にはスッキリすると思いますが、ここでは割愛します。CRUDの中でもCRUの部分だけをとりあげて、簡単なプロフィール画面を作成しました。サービスの雰囲気がつかめるところまでをやってみました。突っ込んだところは別機会にアウトプットしようと思います。694,995iOS開発歴がそこそこ長くなってきました。Swiftが好きなのでSwiftの小ネタ中心にブログを執筆しています。リモート】クラスメソッドの会社説明会を開催しますクラスメソッドでは、AWS・AI・ビッグデータ・モバイルなどの技術職や営業のメンバーとして一緒にお仕事をする仲間を大募集しています。#cmdevio新型コロナウイルスの感染拡大を受け、本イベントを延期させていただくことになりました(開催時期未定)。お申し込みいただいた皆様には大変申し訳ございませんが、何卒ご理解いただけますようよろしくお願いいたします。AWSについてライトに色んな情報交換をしましょう。濱田孝治421re:Invnetの動画検索でもめちゃくちゃ便利ですが、その他ブログやホワイトペーパーやGitHubも横断検索できるので、是非一度使ってみてください。CAFEの他、NTTデータとセブンイレブンの取り組みや、サインポスト、Zippinなどの各社と流通・小売業との連携を業界マップに作成してみました。泰雨122皆さん、こんにちは。コンサル部のテウです。2020年もあっという間に2ヶ月が経ちました。今年こそ機械学習に入門しようぜ!!って決心された方もいらっしゃると思います。入門できる方法をご紹介させて頂きたいと思います。本記事の手順通り、ランチタイム等の時間を活かして、手軽に入門してみてください。濱田孝治421re:Invnetの動画検索でもめちゃくちゃ便利ですが、その他ブログやホワイトペーパーやGitHubも横断検索できるので、是非一度使ってみてください。夏目祐樹414こんにちは、CX事業本部の夏目です。MacのタッチバーのタッチIDが非常に便利なのですが、Terminalでsudoを叩かないと行けないときに使えたらなぁと思ったので、情報を共有します。臼田佳祐296ワークフロー自動化OSSのn8nをAWS環境で建てて検証してみました。非常に期待できるサービスです。Fargateの勉強をしています。使ってみたい方は参考にしてください。洋介257SnowflakeがAWSの東京リージョン上で稼働するようになりました。データを日本に置けます。クラスメソッド株式会社が運営するAWS・iOS・HTML5に関する技術情報サイトです。