【Swift】リアルタイムチャットを実現するFirebaseでCRUD(データ作成、読み込み、更新、削除)をやってみる
こちらを参考にログイン機能ありのTODOアプリを作成しました。
今回学んだのはユーザー情報と投稿情報の紐付け方です。
自分なりの理解をコメントに入れています。
ユーザー情報と投稿情報の紐付け方
viewcontroller.swift
funccreate(){//textFieldになにも書かれてない場合は、その後の処理をしないguardlettext=textField.textelse{return}//ロートからログインしているユーザーのIDをchildにしてデータを作成//childByAutoId()でユーザーIDの下に、IDを自動生成してその中にデータを入れる//setValueでデータを送信する。第一引数に送信したいデータを辞書型で入れる//今回は記入内容と一緒にユーザーIDと時間を入れる//FIRServerValue.timestamp()で現在時間を取るself.ref.child((Auth.auth().currentUser?.uid)!).childByAutoId().setValue(["user":(Auth.auth().currentUser?.uid)!,"content":text,"date":ServerValue.timestamp()])//テスト表示print("user\((Auth.auth().currentUser?.uid)!)content\(text)date\(ServerValue.timestamp())")}
一般的にFirebaseでデータを保存するときは、setValue
で行いますが、今回はunique-post-id
などを生成するためにchildByAutoId
を使いました。おそらく。
メソッド | 一般的な使用例 |
---|---|
setValue | users/user-id/username など、定義済みのパスへのデータの書き込みや、データの置換を行います。 |
childByAutoId | データのリストに追加します。childByAutoId を呼び出すたびに、user-posts/user-id/unique-post-idのような一意の識別子としても使用できる一意のキーが生成されます。 |
updateChildValues | データのすべてを置換することなく、定義済みのパスのキーの一部を更新します。 |
runTransactionBlock | 同時更新によって破損する可能性がある複合データを更新します。 |
データの表示の方法
Java および Node.js では、コールバック関数は DataSnapshot を受け取ります。これはデータのスナップショットです。スナップショットとは、ある時点における特定のデータベース参照にあるデータの全体像を写し取ったものです。スナップショットの val() / getValue() を呼び出すと、データの言語固有のオブジェクト表現が返されます。参照先の場所にデータが存在しない場合、スナップショットの値が null になります。
Listviewcontroller.swift
//Fetchしたデータを入れておく配列、この配列をTableViewで表示varcontentArray:[DataSnapshot]=[]//FetchしたSnapshotsを格納する変数varsnap:DataSnapshot!//Firebaseのルートを宣言しておくletref=Database.database().reference()
xibファイルを使わずに表示する方法
参考にした記事ではxibファイルなどを使ってセル内にcontentを表示してましたが、自分はまだxibファイルの使い方側からなっか他ため、以下のように少し変更して実装しました。
Listviewcontroller.swift
classListViewController:UIViewController,UITableViewDelegate,UITableViewDataSource{@IBOutletweakvartable:UITableView!//送信したデータを表示するTableViewvarcontentArray:[DataSnapshot]=[]//Fetchしたデータを入れておく配列、この配列をTableViewで表示varsnap:DataSnapshot!//FetchしたSnapshotsを格納する変数letref=Database.database().reference()//Firebaseのルートを宣言しておくoverridefuncviewDidLoad(){super.viewDidLoad()//データを読み込むためのメソッドself.read()table.delegate=self//デリゲートをセットtable.dataSource=self//デリゲートをセット// Do any additional setup after loading the view.}overridefuncviewWillAppear(_animated:Bool){super.viewWillAppear(animated)//Cellの高さを調節table.estimatedRowHeight=56table.rowHeight=UITableView.automaticDimension}overridefuncviewDidDisappear(_animated:Bool){super.viewDidDisappear(animated)//画面が消えたときに、Firebaseのデータ読み取りのObserverを削除しておくref.removeAllObservers()}overridefuncdidReceiveMemoryWarning(){super.didReceiveMemoryWarning()// Dispose of any resources that can be recreated.}//ViewControllerへの遷移functransition(){self.performSegue(withIdentifier:"toView",sender:self)}//セルの数functableView(_tableView:UITableView,numberOfRowsInSectionsection:Int)->Int{returncontentArray.count}//返すセルを決めるfunctableView(_tableView:UITableView,cellForRowAtindexPath:IndexPath)->UITableViewCell{letcell=tableView.dequeueReusableCell(withIdentifier:"Cell",for:indexPathasIndexPath)//contetnArrayにitemを代入letitem=contentArray[indexPath.row]//cell内に代入するものをfirebaseから持ってくるlettextlabel=item.valueas!Dictionary<String,AnyObject>//cell内に代入するものを決めるcell.textLabel?.text=String(describing:textlabel["content"]!)returncell}funcread(){//FIRDataEventTypeを.Valueにすることにより、なにかしらの変化があった時に、実行//今回は、childでユーザーIDを指定することで、ユーザーが投稿したデータの一つ上のchildまで指定することになるref.child((Auth.auth().currentUser?.uid)!).observe(.value,with:{(snapShots)inifsnapShots.children.allObjectsis[DataSnapshot]{print("snapShots.children...\(snapShots.childrenCount)")//いくつのデータがあるかプリントprint("snapShot...\(snapShots)")//読み込んだデータをプリントself.snap=snapShots}self.reload(snap:self.snap)})}//読み込んだデータは最初すべてのデータが一つにまとまっているので、それらを分割して、配列に入れるfuncreload(snap:DataSnapshot){ifsnap.exists(){print(snap)//FIRDataSnapshotが存在するか確認contentArray.removeAll()//1つになっているFIRDataSnapshotを分割し、配列に入れるforiteminsnap.children{contentArray.append(itemas!DataSnapshot)}// ローカルのデータベースを更新ref.child((Auth.auth().currentUser?.uid)!).keepSynced(true)//テーブルビューをリロードtable.reloadData()}}}
【Firebase+swift】
— なかむら (@nakamurasssey) November 23, 2019
ユーザーと投稿コンテンツを紐付けてTableViewに表示できるようになたーーー!
これで作りたかったアプリが作れそう! pic.twitter.com/LFaP6A1hO8