標準課題1
ユーザ間で,質問を投稿し,回答を書き込めるようなシステムを作成しましょう.
- 登録ユーザだけが利用可能 (Firebase のプロジェクトにアカウント登録したユーザのみ)
- ユーザは質問を登録可能
- ユーザは質問一覧を見て,回答したい質問に回答を投稿できる
データ構造はこんな感じで良いかと.
/users/
└── {uid}/
├── name: ユーザの名前(例:甲南太郎)
└── ...
/questions/
└── {qid}/
├── name: 質問のタイトル (例:お勧めアンケート)
├── body: 質問内容 (例:お勧めアンケート教えて)
└── sender: 質問の投稿者の uid
/answers/
└── {qid}/
└── {rid}/
├── sender: 回答者の uid
├── target: 質問の qid
└── body: 回答内容 (例:お勧め授業募集中@ qid2)
アクセス用 API
- User 情報は /users/{uid}/ に置く
- GET は,全ユーザ情報取得で OK. (get_users(token))
- PUT で,自分のユーザ情報を更新可能 (put_user(uid, token))
- アンケートは /questions/ に POST (post_question(json_str, token))
- 但し,”sender”: は質問者の uid を入れよう
- GET は,全質問取得で OK. (get_questions(token))
- オプション:PUT を用いた修正(投稿者は自分の投稿したアンケートを qid 指定して上書き可能, put_question(qid, json_str, token))
- アンケート(ID: qid) への回答は/answers/qid/ 以下に POST (post_answer(qid, json_str, token))
- 但し,”sender”: は回答者の id を入れよう
- GET の際は,対象アンケートの ID (qid) を指定して,全回答を取得するので OK (get_answers(qid, token))
- オプション:PUT を用いた修正(回答者は自分の投稿した回答を qid, rid を指定して上書き可能, put_answer(qid, rid, json_str, token))
これで, データベースに読み書きする関数群ができたようなものです. 関数名は,上記に記載したものから修正したり追加してもらって構いません.
上記データ構造用のセキュリティルールについては,あとで載せます.
アプリ完成イメージ
基本系としては,ターミナルアプリとして完成させてくれるので良いです. こんな感じ.while ループで,ユーザから入力を受けつつ,操作に応じた処理(関数に分けると良いかと)をおこなっていく.
> どの操作をしますか? (0: アンケート一覧表示, 1: アンケート投稿, 2: 回答投稿, 3: 回答一覧表示, 9: 終了)
0[enter]
質問1: お勧めアンケート
....
> どの操作をしますか? (0: アンケート一覧表示, 1: アンケート投稿, 2: 回答投稿, 3: 回答一覧表示, 9: 終了)
2[enter]
質問番号を入力てください。
1[enter]
質問2: 本文: お勧めアンケートを教えて
回答を入力してください。
アンケートの回答を色々書く。。。。。。[enter]
質問2に回答[アンケートの回答を色々書く。。。。。。]を登録しました。
> どの操作をしますか? (0: アンケート一覧表示, 1: アンケート投稿, 2: 回答投稿, 3: 回答一覧表示, 9: 終了)
9[enter]
お勧めプログラム作成手順
プログラムですが,クラウドDB利用の完成版のプログラムをコピペして,改変していてけばいいです.
手順としては
- プログラムのコピペをする.データベースは,そのまま同じものを使ってもいいし,改変してもいい.
- ただし,セキュリティルールの変更をお忘れなく.
- で,プログラムは,まずは各 API を準備して,API が動作するかチェックするか,プログラムから試していく
- 一通り確認できたら,今度は,アプリ完成イメージを実現すべく,while ループと各操作内容,API 呼び出しなどを実現していく
てな感じです.
オプション課題
余力がある人は,オプション課題として,色々アプリの機能拡張してもらってもよいかと.
例えば
- 質問の形(選択式とか,複数の設問とか)を拡張
- 質問の際に,回答フォーマットも入力/選択させる
- ユーザ毎の質問一覧機能
- GUI 付けたり などなど.あるいは標準課題2みたいにお絵描き機能をつけていっても構わないかと.
security rule
基本的に
- 登録ユーザは全エリア見える
usersへの書込みは,自分の場所だけ書き込み可能questionsへの書込みは,投稿者だけ書き込み可能- POST で投稿
- オプション:投稿者はあとから修正も可能
answersへの書込みは,回答者だけ書き込み可能- POST で投稿
- オプション:投稿者はあとから修正も可能
というデータ構造にする予定です.こちらで準備したセキュリティルールはこんな感じです.
{
"rules": {
".read": "auth !== null",
".write": false,
"users": {
"$uid": {
".write": "auth.uid === $uid"
}
},
"questions": {
"$qid": {
".write": "auth !== null &&
(newData.child('sender').val() === auth.uid) &&
(!data.exists() || data.child('sender').val() === auth.uid)"
}
},
"answers": {
"$qid": {
"$rid": {
".write": "auth !== null &&
(newData.child('sender').val() === auth.uid) &&
(!data.exists() || data.child('sender').val() === auth.uid)",
}
}
}
}
}
例えば,users はリクエストをおこなった人の uid (auth.uid) が,書き込み場所の uid ($uid) に一致しないとダメってルールになっています.
一方で,questions などでは,以下を要求しています.
- 書き込みデータの
sender(newData.child('sender').val(), 属性がない場合は null を返す)と投稿者の uid (auth.uid) が一致すること - データがない場所への書込みであるか (
!data.exists()),データがあった場合はそのsenderが 投稿者のuid に一致すること
本当をいうと,回答の投稿が,存在する設問に対する回答であるかチェックしたりとかしてもいいのですが,あまり複雑になり過ぎると読む気がしないでしょうから,ここまでってことで.