ReactNative × FirestoreでiOSアプリを作成する手順とまとめ
概要
CloudFirestoreとは
Firebaseが提供している、NoSQLベースのデータベースのうちの一つ(MBaasの一つ)
RealtimeDatabase → CloudFirestoreに進化!
Q、何が改善されてる?
A、データモデルの改善、クエリ強化されている。
Firebaseの機能とデータベース
準備
Firebaseプロジェクトのセットアップ
Firebase公式ページからコンソール画面に移動して、新規アプリ作成。
プロジェクトIDとロケーションは後で変更が出来ないので、注意!
※国内向けサービスの場合、asia-northeast1(東京)or asia-northeast2(大阪)
バックエンド側のセットアップ
- Firebase CLIをインストールする。これを使うと、Firebaseを使った開発がより効率的になる。
npm install firebase-tools
- デプロイを可能にするためにセットアップする。
npm firebase login
Firestoreをセットアップ
最初はテストモードで開始。
- npmモジュールの追加
npm install @react-native-firebase/app
iOSアプリ開発環境のセットアップ
CocoaPods経由でFirebaseをインストール。
Finderで、「プロジェクト名」→「ios」→「podfile」を開く。podfile内にテキストで以下を記述する。
target 'Project' do pod 'Firebase/Core' pod 'Firebase/Auth' pod 'Firebase/Firestore' pod 'Firebase/Functions' end
iosアプリにFirebaseを作成するページで以下の流れに沿って進める。
- pod install
cd ios/ && pod install
- Firebase SDKのセットアップ
npm install @react-native-firebase/app npm install @react-native-firebase/auth npm install @react-native-firebase/firestore
実装(データの操作)
- CollectionとDocumentの取得、追加
import firestore from '@react-native-firebase/firestore'; // 'Users'というCollectionの、'KHarada'というDocumentを指定 const userDocument = firestore() .collection('Users') .doc('kHarada'); // 取得 .get() // 追加 .set()
AuthenticationアカウントとFirestoreドキュメントの作成
新規登録画面で入力されたメールアドレス等をfirestoreドキュメントにぶちこむ。
handleSubmit = async () => { try { // メールアドレス認証 let res = await auth() .createUserWithEmailAndPassword(this.state.email, this.state.password) .catch((err) => { console.log(err); }); // ドキュメント内に保存するフィールド let userData = { uid: res.user.uid, email: this.state.email, }; // userDataを保存する await firestore() .collection('users') .doc(res.user.uid) .set(userData); console.log('email login success'); this.props.navigation.navigate('App'); } } catch (e) { console.log(e.message); } };
クエリの機能と種類
クエリを使いこなすことで、firestore内に保存されているデータを制御し、自在に操作することが可能
条件制限
where
Ex, 18歳以上のみ取得したいとき
firestore() .collection('Users') // 18歳以上のみ .where('age', '>=', 18) .get()
- 件数制限
limit
ドキュメントの数を制限したいとき
firestore() .collection('Users') // 18歳以上のみ .where('age', '>=', 18) // ドキュメントを20こまで .limit(20) .get()
- 並べ替え
order By
firestore() .collection('Users') // 降順で並べ替え .orderBy('age', 'desc') .get()
- 特定のポイントから開始/終了
start At / end At
firestore() .collection('Users') .orderBy('age', 'desc') // 18歳から30歳まで .startAt(18) .endAt(30) .get()
startAtでリロード後の追加データをどのポイントから取得するのか指定する。
Firestoreの課題
-
マイグレーション:ソフトウェアやシステム、データなどを別の環境に移転したり、新しい環境に切り替えたりすること。
データのエクスポートが出来ない。バックアップする方法がない。
(このデメリットはさほど気にならない気もする・・)
データベース設計
データの形式が自由なだけあって、フィールドに書き込んだデータの型がわからなかったりする。
チーム内でのドキュメント作成と共有が重要。
検索
ネイティブインデックスの作成やドキュメント内のテキストフィールドの検索をサポートしていないので、Algoliaという検索APIを使って、検索周りはそっちに任せる。
Firebaseでバックエンドエンジニア不在のアプリ開発 クックパッドが体感した、メリットと課題 #エンジニアHub - エンジニアHub|若手Webエンジニアのキャリアを考える!
Firestoreを今まで触ってみて思ったこと
- プロジェクトの規模にもよるが、とにかく機能が充実していて、あまり不便さを感じていない。なので、RDBの必要性が見えてこない。
- Authenticationは多くのSNSと連携することが可能なので、モダンなプロダクトにはもってこい
- 多くの企業が利用しているせいか、日本語の記事が多い印象。初心者に優しい。
参考ページ
CodeIgniterのMVCモデル
CodeIgniterのMVCモデルの書き方をメインに書いています。
Controller
静的なページを作成するためのクラスを実装したコントローラを作成する。
作成するクラスは、system/core/Controller.php の CI_Controller クラスを継承させる。
引数にページの名前を取る。
そのページをロードするメソッドは、show()
class Pages extends CI_Controller { public function show($page = 'home') { } }
- クラスの継承
- オーバーライド:小クラスと親クラスで同じメソッドを使用した場合、コクタスが優先され、親クラスを上書きする。
メソッド
特殊な役割を持つメソッド
function __construct() { // 親コントローラクラスのコンストラクタを呼び出す parent::__construct(); }
- プライベートメソッド:_任意のメソッド名()
- URLから直接アクセスできない。
- 以下のような書き方で、デフォルトメソッドを経由して呼び出される。
function index()
{
echo $this->_private_method();
}
function _private_method()
{
echo 'プライベートメソッドです';
}
View
- 特徴
- Viewの読み込み
$this->load->view('ファイル名', データの連想配列 or オブジェクト)
<?php class Hello extends CI_Controller { // index()メソッドの中身>>'Hello World' public function index() { echo "Hello World"; } // about()メソッドの中身>>about.php public function about() { $this->load->view('about'); } } ?>
- ループ
- foreach構文を使って繰り返し処理を行う。
// Controller function index() { $data["title"] = "サンプル" $data["contents"] = array("りんご", "みかん") $this->load->view("ファイル名", $data); }
<title><?=$title?></title> . . . <ul> <?php foreach($contents as $item):?> <li><?=$item;?></li> <?php endforeach;?> </ul>
Model
- Modelの書き方
<?php class Model_name extends CI_Model { public function __construct() { parent::__construct(); } } ?>
- Modelの読み込み
- 読み込み
// /system/application/models/read/read.phpを読み込みたいとき $this->load->model('read/read');
- メソッドの実行
$this->read->function();
CodeIgniterのデータベース接続方法
データベースへの接続
なるべく自動接続。理由は手動接続はすべてのコントローラの接続を作成する必要があるため。
自動接続
application/config/autoload.phpを使用して行う
php $autoload['libraries'] = array('database');
手動接続
特定のコントローラのデータベース接続が必要な場合に使う。
php $this->load->database();
PHPでの開発を始めるので、概要をまとめてみた
役割
- HTMLを作ること
- データを管理すること
ローカル開発環境
サーバーにアップせずにPHPが書き換えたHTMLを確認するために必要な作業
必要なインストール
- PHP
- Webサーバー
上記はインストールがかなり難しい。
なので、インストールをアシストしてくれる、XAMPPやMAMPを使う。
MAMPとは
Macintosh、Apache、MySQL、PHPを省略してつなげた名前。
簡単にWeb開発環境を立ち上げられるようにするために必要なソフトウェアをパッケージ化したもの。
XAMPPとほぼ一緒。開発元が違う。
コードの書き方
// 最初に<?php ?> で囲う。 <?php echo 'こんにちは!'; // こんにちは!と表示される。 ?> <?php echo 'こんにちは!' . date('l'); // こんにちは!Mondayと表示される。 ?> // 変数 <?php $message = 'こんにちは' . date('l'); ?> <?= $message; // こんにちは!Mondayと表示される ?> // 乱数 <?php $n = mt_rand(1, 3) // 1以上3以下 ?> // ファイルをインポートする <?php include('ファイル名') // この記述だけで反映される // 以降にHTML記述がなければ、閉じタグ不要 ?> // HTMLタグの中に文字列を記述する時 <title> <?= htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); // 別ファイルで表示させたい値を、$titleに代入する ?> PHPのサイト </title> // キャスト <?php $x = (string) 10; // int型の10を、string型の'10'に変換 ?> // 変数を調査するとき <?php var_dump($x) ?> // 連想配列(JSだとオブジェクトに近い?) <?php $hashira = [ '水柱' => '冨岡義勇' // key => value ]; echo $hashira['水柱']; // 冨岡義勇と表示される // keyはstring型かint型のみOK ?> // 関数の定義 <?php function 関数名($引数1, $引数2) { // 処理 return 返り値; } 関数名($実引数1, $実引数2); ?> // アクセス修飾子 <?php class Human{ // プロパティ public $name; // プロパティをクラスの外に公開する protected $birthday; private $gender; // プロパティをクラスの外に公開しない。基本的にprivate // メソッド public function walk() { echo '歩く'.PHP_EOL; } public function eat() { echo '食べる'.PHP_EOL; } } ?> // コンストラクタ(上の続き) <?php $human = new Human(); $human -> eat(); $human -> walk(); ?>
Rubyの基礎文法を簡単にまとめてみた
ハッシュ
#key:valueをひとかたまりに格納する fruits = {"a":"apple", "b":"grape", "c":"orange"} puts fruits puts fruits[:a] #キー値で取り出す #実行結果 {:a=>"apple", :b=>"grape", :c=>"orange"} apple
条件分岐
if 条件A 条件に一致した場合の処理 elsif 条件B 条件Aと一致せず、条件Bに一致したの時の処理 else 条件A, Bのどちらにも一致しない時の処理 end
インデント
rubyでは、tabキーでインデントはNG!
スペースキーでインデント作る!
繰り返し処理
for文
list = [1, 2, 3, 4, 5] for item in list puts item end #実行結果 1 2 3 4 5
while文
a = 1 while a <= 10 do puts a a += 1 end #実行結果 1 2 3 4 5 6 7 8 9 10
例外処理
begin
begin 実行するコード rescue 例外が発生したときだけ実行されるコード else 例外が発生しなかったときだけ実行されるコード end
rescue
begin 実行するコード rescue 例外が発生したときだけ実行されるコード else 例外が発生しなかったときだけ実行されるコード ensure 例外の有無にかかわらず 最後に実行されるコード end
raise
raise エラーの種類
メソッド
#メソッド def drinkServer(fruit) drink = fruit + 'ジュース' return drink end puts drinkServer('りんご') #出力結果 りんごジュース
クラス
メソッドなどの処理全体のひとかたまり
#円についての処理をするクラスを宣言 class Circle #クラス名の最初は大文字 def area_circle puts @radius * @radius * 3.14 end #関数などが連続するときは間に空行を1行入れること def circumference puts @radius * 2 * 3.14 end def radius=(radius) @radius = radius end end #インスタンスを生成 circle1 = Circle.new #半径を入力 circle1.radius = 3 #関数を呼び出す circle1.area_circle circle1.circumference
継承クラス
class クラス名 < 継承したいクラス名 end
初心者のためのRuby入門徹底ガイド【基礎からわかりやすく解説】 | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト