もっぺんプログラミング(´・ω・`)

もっぺん頑張って副業プログラマを目指してます。

100日後にFlutter生活:18日目:ログイン画面をパクってみる。(つづき)

引き続き、Youtube動画を見ながら FlutterのUIを勉強中です。
3:30くらいまで来ました。

www.youtube.com

Email 入力欄を追加しました。
ふむふむ。

f:id:momoizo:20210204024315p:plain

Container のWidgetでも、decoration、borderRadius、boxShadow などを上手く使えば、オシャレに見えますね!
センタリングなどは、Column に任せればいいということなのかな。

child: Padding(
  padding: EdgeInsets.all(20),
  child: Column(
    children: <Widget>[
      SizedBox(
        height: 60,
      ),
      Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(10),
          boxShadow: [
            BoxShadow(
                color: Color.fromRGBO(225, 95, 27, .3),
                blurRadius: 20,
                offset: Offset(0, 10))
          ],
        ),
        child: Column(
          children: <Widget>[
            Container(
              decoration: BoxDecoration(
                border: Border(
                  bottom: BorderSide(color: Colors.grey[200]),
                ),
              ),
              child: TextField(
                decoration: InputDecoration(
                    hintText: "Email or Phone number",
                    hintStyle: TextStyle(color: Colors.grey),
                    border: InputBorder.none),
              ),
            ),
          ],
        ),
      ),
    ],
  ),
),

100日後にFlutter生活:18日目:ログイン画面をパクってみる。

以下の動画で作っているログイン画面を丸パクリしてみます。

僕も、こんなカッコいい画面を作れるようになりたい!

www.youtube.com

途中(1:54 あたり)まで実装したところで、明日に続きます。 サクサクリロードして画面を見ながら作れるのは、快適だね〜

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
      home: HomePage(),
    ));

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
          padding: EdgeInsets.symmetric(vertical: 30),
          width: double.infinity,
          decoration: BoxDecoration(
            gradient: LinearGradient(begin: Alignment.topCenter, colors: [
              Colors.orange[900],
              Colors.orange[800],
              Colors.orange[400],
            ]),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              SizedBox(height: 80),
              Padding(
                  padding: EdgeInsets.all(20),
                  child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text("Login",
                            style:
                                TextStyle(color: Colors.white, fontSize: 40)),
                        SizedBox(height: 10),
                        Text("Welcome back",
                            style:
                                TextStyle(color: Colors.white, fontSize: 18)),
                      ])),
              Expanded(
                  child: Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius:
                              BorderRadius.only(topLeft: Radius.circular(60)))))
            ],
          )),
    );
  }
}

100日後にFlutter生活:17日目:Firebase Realtime Database にレコード追加出来た!

今日は時間がなかったんだけど、サンプルコードのまま書いてみたら、Firebase Realtime Databaseにレコード追加出来ました!

いやっほい!

結局、パッケージ追加してビルドが通るまでのハマりが最も苦戦したんだけど、そこさえ突破できれば、サンプルコードを切り貼りしながら試す段階なので、なんとかなる。
というか、ここから楽しくなってくるとこー!

書いたコードの抜粋

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';

...

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final FirebaseApp app = await Firebase.initializeApp();

...
class _MyHomePageState extends State<MyHomePage> {
  DatabaseReference _messageRef;

  @override
  void initState() {
    super.initState();
    final FirebaseDatabase database = FirebaseDatabase(app: widget.app);
    _messageRef = database.reference().child('messages');
  }

  Future<void> trySubmit() async {

    _messageRef.push().set(<String, String>{'hello': 'world'});

...

100日後にFlutter生活:16日目:Firebase Auth パッケージが使えた!

今日は、サンプルコードを動かすところ。

こちらのコードを参考にさせていただいています。

GitHub - daiki1003/firebase_sample at firebase_auth_package

画面は一つのみで、テキストボックスが2つとボタンがあるのみです。
テキストボックスにメールアドレスとパスワードを入れて、ボタンを押したら認証APIを呼び出すという簡単なサンプルです。

こういうサンプルを公開してもらえるのは、ありがたいですね。

キモは、以下の部分

  Future<void> trySubmit() async {
    if (!_form.currentState.validate()) {
      return;
    }

    _form.currentState.save();

    final auth = FirebaseAuth.instance;
    if (_isLogin) {
      final result = await auth.signInWithEmailAndPassword(
          email: _email, password: _password);
      print(result.user.uid);
    } else {
      final result = await auth.createUserWithEmailAndPassword(
          email: _email, password: _password);
      print(result.user.uid);
    }
  }

とりあえず、実行したら「FirebaseAuth.instance;」のところで、以下のエラーが出ました。(´・ω・`)

[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()
#0      MethodChannelFirebase.app
package:firebase_core_platform_interface/…/method_channel/method_channel_firebase.dart:118
#1      Firebase.app
package:firebase_core/src/firebase.dart:53
#2      FirebaseAuth.instance
package:firebase_auth/src/firebase_auth.dart:37
#3      _MyHomePageState.trySubmit
package:firefire/main.dart:67
#4      _InkResponseState._handleTap
package:flutter/…/material/ink_well.dart:993
#5      _InkResponseState.build.<anonymous closure>
package:flutter/…/material/ink_well.dart:1111
#6      GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:183
#7      TapGestureRecognizer.handleTapUp
package:flutter/…/gestures/tap.dart:598
#8      BaseTapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:287
#9      BaseTapGestureRecognizer.acceptGesture (pac<…>
[VERBOSE-2:profiler_metrics_ios.mm(184)] Error retrieving thread information: (ipc/send) invalid destination port

どこかで、Firebase.initializeApp() を呼ばないとだめだったんでしょうか…

調べたら、すでに対応されてる方がおられました。
ありがたや。

qiita.com

真似して、main メソッドを編集したら、無事APIが動いてGoogle Firebase 上にユーザー登録されました!
いやっほー!

import 'package:firebase_core/firebase_core.dart';
...

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

Firebase authを使うまでの道のりを整理すると…

  1. firebase_coreと、firebase_authパッケージをflutter にインストールする。
  2. Google Firebaseのドキュメントに従ってセットアップする。(「アプリにFirebaseを追加する
  3. Podsfile のターゲットを ios 10 以上にする。(上記ドキュメントにも書いてた)
  4. Firebase.initializeApp を適切なタイミングで実行する。

これで、動く!はず!

100日後にFlutter生活:15日目:Firebase Auth API 呼び出しで、iOSビルドエラー

Flutterで、Firebaseのauthentication を使おうとして、iOS ビルドエラーになった状況を解決までを書いておきます。
いろいろ試したので、決定的な解決方法が曖昧ですが、おそらく Podfile の ios ターゲットが低かったせいかなと…

環境

Flutter のバージョンは、こんな感じ。

flutter % flutter --version
Flutter 1.22.6 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 9b2d32b605 (8 days ago) • 2021-01-22 14:36:39 -0800
Engine • revision 2f0af37152
Tools • Dart 2.10.5
flutter % 

Mac OS Big Sur 11.1 XCode Version 12.4 (12D4e)

で、やってます。
以下、ハマりポイントまでの操作手順。

プロジェクトを作る

flutter create でプロジェクトを作成。
サンプルが動くところまで進める。

flutter % flutter create firefire
Creating project firefire...
  firefire/ios/Runner.xcworkspace/contents.xcworkspacedata (created)
…

All done!

[✓] Flutter: is fully installed. (Channel stable, 1.22.6, on macOS 11.1 20C69 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices: is fully installed. (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS: is fully installed. (Xcode 12.4)
[✓] Android Studio: is fully installed. (version 4.1)
[✓] VS Code: is fully installed. (version 1.52.1)
[✓] Connected device: is fully installed. (1 available)

In order to run your application, type:

  $ cd firefire
  $ flutter run

Your application code is in firefire/lib/main.dart.

flutter % 

VS Code で開いて、Debug!

flutter % cd firefire
firefire % code .

ここまでは、サンプルコードが動いてる。
問題なし。

firebase_auth をインストール

ここから、おかしくなる(´・ω・`)

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  firebase_auth: ^0.21.0-nullsafety.0

で、flutter pub get すると…

firefire % flutter pub get
The current Dart SDK version is 2.10.5.                                 
                                                                        
Because firefire depends on firebase_auth >=0.21.0-1.0.nullsafety.0 which requires SDK version >=2.12.0-0 <3.0.0, version solving failed.
Running "flutter pub get" in firefire...                                
pub get failed (1; Because firefire depends on firebase_auth >=0.21.0-1.0.nullsafety.0 which requires SDK version >=2.12.0-0 <3.0.0,
version solving failed.)
firefire % 

あかんぽい。
Dart SDKのバージョンをアップしないとダメ?

でも、Dartのページだと 2.10.5 が Stable となってるから、悪くないと思うんだけどなぁ。(2021/01/30 時点)
Get the Dart SDK | Dart

どうやるのか…

firebase_authのバージョンを変えてみる。

dependencies:
  flutter:
    sdk: flutter
  firebase_auth: ^0.20.0+1

しかし、やはり以下のエラーでダメ

Launching lib/main.dart on iPhone 12 Pro Max in debug mode...
 lib/main.dart
CocoaPods' output:
↳
      Preparing
    Analyzing dependencies
    Inspecting targets to integrate
      Using `ARCHS` setting to build architectures of target `Pods-Runner`: (``)
    Fetching external sources
    -> Fetching podspec for `Flutter` from `Flutter`
    -> Fetching podspec for `firebase_auth` from `.symlinks/plugins/firebase_auth/ios`
    firebase_auth: Using Firebase SDK version '7.3.0' defined in 'firebase_core'
    -> Fetching podspec for `firebase_core` from `.symlinks/plugins/firebase_core/ios`
    firebase_core: Using Firebase SDK version '7.3.0' defined in 'firebase_core'
    Resolving dependencies of `Podfile`
      CDN: trunk Relative path: CocoaPods-version.yml exists! Returning local because checking is only perfomed in repo update
    [!] CocoaPods could not find compatible versions for pod "firebase_auth":
      In Podfile:
        firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
    Specs satisfying the `firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)` dependency were found, but they required a higher minimum deployment target.
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolution.rb:328:in `raise_error_unless_state'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolution.rb:310:in `block in unwind_for_conflict'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolution.rb:308:in `tap'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolution.rb:308:in `unwind_for_conflict'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolution.rb:684:in `attempt_to_activate'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolution.rb:254:in `process_topmost_state'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolution.rb:182:in `resolve'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/molinillo-0.6.6/lib/molinillo/resolver.rb:43:in `resolve'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/resolver.rb:94:in `resolve'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/installer/analyzer.rb:1074:in `block in resolve_dependencies'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/user_interface.rb:64:in `section'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/installer/analyzer.rb:1072:in `resolve_dependencies'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/installer/analyzer.rb:124:in `analyze'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/installer.rb:414:in `analyze'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/installer.rb:239:in `block in resolve_dependencies'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/user_interface.rb:64:in `section'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/installer.rb:238:in `resolve_dependencies'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/installer.rb:160:in `install!'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/command/install.rb:52:in `run'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:334:in `run'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/command.rb:52:in `run'
    /Users/xxxx/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/cocoapods-1.10.1/bin/pod:55:in `<top (required)>'
    /Users/xxxx/.rbenv/versions/2.6.6/bin/pod:23:in `load'
    /Users/xxxx/.rbenv/versions/2.6.6/bin/pod:23:in `<main>'
Error output from CocoaPods:
↳
    [!] Automatically assigning platform `iOS` with version `9.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
Error running pod install
Error launching application on iPhone 12 Pro Max.
Exited (sigterm)

うーん。このエラーなのかな〜

[!] CocoaPods could not find compatible versions for pod "firebase_auth":
In Podfile:
firebase_auth (from .symlinks/plugins/firebase_auth/ios)

類似のエラーで、StackOverflow 見てみたけど、良くわからん… ios - CocoaPods could not find compatible versions for pod "Firebase/CoreOnly" - Stack Overflow

flutter clean
pod repo update

を、やってみたけど解決せず。

Firebaseのドキュメントを見てみる

手がかりを求めて、Firebaseのドキュメントへ…

Add Firebase to your iOS project

platform :ios, ‘10.0’

Podfileのplatform は、10.0 じゃないとダメなのかな?
上記エラーメッセージで、「[!] Automatically assigning platform iOS with version 9.0」とあり
iOSのバージョンが低すぎたのかもしれない。

Podfile に上記を追加して、シュミレーターとVS Code も念の為再起動。(VS Codeは、関係なさそうだけど…) ビルドは通った!

ドキュメントに記載されていた、「pod 'Firebase/Auth'」も、一応、Podfileに追記
書いた場所は、なんとなく。
やはり、Swiftの開発知識がないと、XCodeの作法がわからないな〜・・・

target 'Runner' do
  pod 'Firebase/Auth'

とりあえず、アプリが起動したので、明日はコードを書いていきます。

100日後にFlutter生活:14日目:Firebaseで認証を

今どき、いろんな方がブログを公開してくださってるので、プログラミング学習は 本当に楽になりましたよね。ありがたや。

本日は、Firebaseの認証を使ってみます。(他の方のブログを見ながら)

blog.dalt.me

パッケージのインストール方法についても秀逸

blog.dalt.me

素晴らしいなぁ。

とりあえず、GitHub からサンプルコードを取得して、JSON連携は動いたぽい。

GitHub - daiki1003/firebase_sample at firebase_auth_web

明日、ソースの中身を詳しくみていきたい…

100日後にFlutter生活:13日目:明日からFirebaseやる。と、心に誓う

今日は眠すぎてダメだー。 なので、明日に向けて準備のみ。

本のサンプルコードが難しすぎるので、別でFirebaseの組み込みを試してみようかな。

codelabs.developers.google.com

明日からチャレンジ!

今日は寝まーす。