新機能のお知らせ

執筆:2023年8月27日

新機能のお知らせです。
近日、新機能として掲示板、通称「みんなの声」を追加致します。
伊勢志摩のリアルタイムな情報などを書き込んでいきたいと思っています。
是非ともお気軽にご利用ください。

Flutter SDKバージョンを管理する

2023年8月20日

開発環境
OS:Windows 11
SDK:VS Code + Flutter 3.7.5

概要

プロジェクト毎にFlutter SDKのバージョンを使い分ける方法です。

Flutter SDKのバージョン管理

Flutter SDKの開発サイクルは早いです。

日々、機能改善、機能追加が行われており、それに伴い、SDKバージョンも上がっています。

今現在(2023.08.20)の最新バージョンは、3.13.0です。

(SDKバージョンはこちらをチェック)

最新バージョンを使うことで既存機能やセキュリティの向上、新しい機能が利用できるなどのメリットがありますが、

その一方、バージョンが上がることによって問題になるのが挙動やI/Fの変更です。

自身がコーディングした箇所でバージョン違いによるI/Fの問題が発生する分には対応できますが、

組み込んでいるパッケージ内で最新バージョンに対応できないエラーが出るとお手上げです。

そこでそのようなバージョン違いによるパッケージ内エラーが発生するプロジェクトでは、

Flutter SDKのバージョンを開発当時のまま使用することでエラーの発生を抑えます。

(特にFlutter SDKバージョン2.x.x→3.x.xのバージョンアップはエラーが出やすいです。)

Flutte SDKバージョン管理ツール、fvmを使用します。

fvmをインストールする

まずはfvmをインストールします。

インストール手順については下記を参照してください。

Flutterプロジェクトにfvmを設定する

fvmで管理したいプロジェクトのフォルダに移動し、fvmコマンドを実行します。

コマンド内容
fvm releasesFlutter SDKのリリースバージョンをリスト表示する
fvm use (version)使用するバージョンを指定する
fvm install (version)指定バージョンのFlutter SDKをインストールする
fvm listインストール済みバージョンをリスト表示する
fvm remove (version)指定バージョンを削除する

※fvm useコマンドは、Windowsの場合、管理者権限のあるコマンドプロンプトで実行する必要があります。

fvmの設定が完了するとプロジェクトフォルダ内に.fvmが作成されます。

fvmを使用する

後はflutterコマンドの前にfvmを付けて使用します。

アプリを実行するなら、

fvm flutter run -d (実行対象)

アプリを作るなら、

fvm flutter build appbundle

今回は以上です。

Windowsにfvmをインストールする

2023年8月20日

開発環境
OS:Windows 11
SDK:VS Code + Flutter 3.7.5

概要

Flutter SDKのバージョン管理ツール、fvmをインストールします。

Chocolateyをインストールする

Windowsでfvmをインストールする場合、

Chocolatey(ソフトウェア管理ツール(無料))を使ってインストールすることになります。

そのため、まずはChocolateyをインストールします。

管理者権限のパワーシェルを起動し、下記コマンド※を入力します。

※複数行で表示されていますが、1つのコマンドです。

(詳細は、こちら

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(‘https://community.chocolatey.org/install.ps1’))

途中、キー入力が必要ですが、「Y」か、「A」を入力すればインストールが継続します。

これでChocolateyがインストールできました。

fvmをインストールする

次に管理者権限のパワーシェルで下記コマンドを入力し、fvmをインストールします。

choco install fvm

こちらも途中、キー入力が必要です。「Y」か、「A」でインストールが継続します。

これでfvmのインストールが完了。

のはずですが、コマンドプロンプトで「fvm –version」と入力しても動作しませんでした。

fvmのインストールが失敗する要因

どうやらfvmのインストールが失敗しているようです。

もう1度、fvmインストールコマンド「choco install fvm」を実行し、

キー入力の場面で「P」を入力し、実行スクリプトを確認してみます。

スクリプトを見ると、

dart pub getで何かを取得し、dart compileを使ってfvm.exeを作成する。

という流れのようです。

スクリプトが成功するとC:\ProgramData\chocolatey\lib\fvm\binにfvm.exeができるよう

ですが、フォルダの中を確認してみると存在しません。

つまり、dart compileでfvm.exeが作れていないってことのようです。。。

そこで最初に実行した「choco install fvm」コマンドの実行結果を見直してみると・・・

Error: Unable to find git in your PATH.

エラーが出ていました。

「git」が見つからない、だと。

gitをインストールする

PCに「git」がインストールされていないのが問題だったようです。

そこで管理者権限のパワーシェルで下記コマンドを入力し、gitをインストールします。

choco install git

こちらも同様、途中、キー入力が必要です。「Y」か、「A」でインストールが継続します。

もう一度、fvmをインストールする

gitのインストールが完了したので再度、fvmをインストールします。

fvm自体はすでにインストール済み、スクリプトが失敗した状態なので

強制インストールのオプション付きでインストールコマンドを実行します。

choco install fvm –force

ついに成功しました。

これでfvmが使用できます。

Macにfvmをインストールする

ちなみにMacにfvmをインストールする場合は下記コマンド。

brew install fvm

Homebrewがインストールされていれば、これだけでインストールできます。

(Windows)Chonolatey = (Mac)Homebrewって感じですね。

今回は以上です。

二見浦海水浴場

執筆:2023年8月19日

2023年の夏も終わりが近づいてきました。
ここ2、3年せっかくの夏にも関わらず夏らしいことをしていなかったな、なんて思ったら、無性に泳ぎたくなりまして久振りに二見浦海水浴場に行ってきました。
ここは伊勢神宮125社の1社、御塩殿神社のすぐ近くにある公設海水浴場で水質はそれほどですが、遠浅の穏やかな海が楽しめます。
二見浦といえば、お伊勢参りの参拝者が二見浦の浜辺で海水を浴び、身を清めて伊勢神宮を訪れたとも言われています。
伊勢神宮参拝の前に訪れてみてはいかがでしょうか?

Webサイトを表示する

2023年8月5日

開発環境
OS:Windows 11
SDK:VS Code + flutter 3.7.5

概要

Webサイトを表示します。

Webサイトを表示する方法

flutterでWebサイトを表示する方法は2パターンあります。

Webブラウザを起動させて表示する方法と

ウィジェットWebViewを用意し、ウィジェットに表示させる方法です。

パターン1.Webブラウザを起動させて表示する

まずはパッケージ、url_launcher(ver 6.1.11)を導入します。

パッケージ詳細はこちら

コマンド入力する場合は、プロジェクトフォルダまで移動した後、下記を入力します。

flutter pub add url_launcher

あとは、launchUrlString(URL)をコールするだけです。

今回は、関数化し、ボタンタップ時に実行させるようにしました。

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

void _openUrl() async {
  const url = 'https://messageexchanger-fa3e1.web.app';
  if (await canLaunchUrlString(url)) {
    await launchUrlString(url);
  } else {
    throw 'can not access this url.';
  }
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: double.infinity,
        height: double.infinity,
        alignment: Alignment.center,
        child: Column(
          children: <Widget>[
            Expanded(
              flex: 1,
              child: Container(
                alignment: Alignment.center,
                child:Image.asset('images/sample.jpg'),),),
            Expanded(
              flex :1,
              child: Container(
                alignment: Alignment.center,
                child: ElevatedButton(
                  onPressed: () async {
                    _openUrl();
                  },
                  style: ElevatedButton.styleFrom(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(5),
                    ),
                  ),
                  child: const Text('Web'),
                  ),))
          ],
        ),
      ),
    );
  } 
}

Chromeで実行した結果、Webサイトが表示されました。

起動時
ボタンタップ後

Androidで実行する場合は、AndroidManifest.xmlにqueries定義を追加する必要があります。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sample">

    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>
    </queries>

   <application
        android:label="sample"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">

  ・・・
起動時
ボタンタップ後

パターン2.ウィジェットWebViewを用意し、ウィジェットに表示させる

まずはパッケージ、webview_flutter(ver4.2.2)を導入します。

パッケージ詳細はこちら

コマンド入力する場合は、プロジェクトフォルダまで移動した後、下記を入力します。

flutter pub add webview_flutter

あとは、ScaffoldのbodyにWebViewWidgetを配置するだけです。

今回は、メイン画面とサブ画面の2画面を作成し、メイン画面でボタンタップするとWebViewWidgetを配置したサブ画面に遷移させるようにしてみました。

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class SubPage extends StatelessWidget  {
  const SubPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:WebViewWidget(
            controller: WebViewController()
              ..setJavaScriptMode(JavaScriptMode.unrestricted)
              ..loadRequest(Uri.parse("https://messageexchanger-fa3e1.web.app"))
          ),
    );
  }
}

Androidアプリで実行した結果、Webサイトが表示されました。

メイン画面
サブ画面

WebViewの注意点

webview_flutterのパッケージ詳細を見ると

サポート対象機種が、AndroidとiOSとなっています。

サポート対象に記載のないChromeで表示するとサブ画面表示のタイミングでダウンしました。

Chromeでは使用できないようです。

今回は以上です。

ビルドエラー解消(minSdkVersion)

2023年8月5日

開発環境
OS:Windows 11
SDK:VS Code + flutter 3.7.5

概要

パッケージ、webview_flutterを導入したところ、Androidアプリをビルドするときにエラーが出てしまいました。

今回は、ビルドエラーを解消します。

ビルドエラー

パッケージ、webview_flutterを導入し、Androidでデバッグしようとビルドした結果、

出力されたエラーがこちら。

デバッグコンソールに出力された内容を確認してみると、

minSdkVersionが16だと利用できない、とのこと。

さらに読み進めるとエラー解消方法が出力されていました。

┌─ Flutter Fix ─────────────────────────────────────────────────────────────────────────────────┐
│ The plugin webview_flutter_android requires a higher Android SDK version.                     │
│ Fix this issue by adding the following to the file                                            │
│ D:\work\vscode\sample2-2\android\app\build.gradle:                                            │
│ android {                                                                                     │
│   defaultConfig {                                                                             │
│     minSdkVersion 19                                                                          │
│   }                                                                                           │
│ } 

android/app/build.gradleのminSdkVersionの値を19にするらしい。

build.gradle

デバッグコンソールに出力されてエラー解消方法に従い、

build.gradleを確認してみると

minSdkVersionには、flutter.minSdkVersionが設定されていました。

flutter.minSdkVersionを追ってみたところ、

$flutterRoot/packages/flutter_tools/gradle/flutter.gradle内で定義を確認することができました。

(私の環境では、flutterRootはD:\work\apps\flutterでした。)

class FlutterExtension {
    /** Sets the compileSdkVersion used by default in Flutter app projects. */
    static int compileSdkVersion = 33

    /** Sets the minSdkVersion used by default in Flutter app projects. */
    static int minSdkVersion = 16

    /** Sets the targetSdkVersion used by default in Flutter app projects. */
    static int targetSdkVersion = 33

  ・・・

    /** Allows to override the target file. Otherwise, the target is lib/main.dart. */
    String target
}

flutter.minSdkVersionの定義値は16でした。

改修方針

flutter.gradleのminSdkVersionの定義値を16から19に変更したいところですが、

flutter.gradleは、全てのアプリが参照する共有ファイルです。

他のアプリへの影響を考慮すると変更できません。

と、いうことでアプリ内のbuild.gradleのminSdkVersionを変更します。

minSdkVersionを固定値「19」に置き換えました。

(結局のところ、デバッグコンソールの指示通りです。

ビルド結果

build.gradleの修正後、デバッグ実行した結果、正常に起動しました。

エラー要因

そもそも今回、なぜビルドエラーがでたのか?

導入したパッケージ、webview_flutterについてパッケージサイト、pub.devを確認したところ、AndroidのSupport SDKは、19以上と記載されていました。。。

今回は以上です。

Dockerコンテナ削除

DockerのGUIでもコンテナを削除できますが、ターミナルならコマンド1発。

docker-compose down –rmi all –volumes –remove-orphans

使い方: down [オプション]

オプション:
    --rmi type
       イメージの削除。type は次のいずれか:
          'all': あらゆるサービスで使う全イメージを削除
          'local': image フィールドにカスタム・タグのないイメージだけ削除

    -v, --volumes
       Compose ファイルの `volumes` セクションの名前付きボリュームを削除
       また、コンテナがアタッチした匿名ボリュームも削除

    --remove-orphans
       Compose ファイルで定義していないサービス用のコンテナも削除

    -t, --timeout TIMEOUT
       シャットダウンのタイムアウト秒を指定(デフォルト: 10)

今月のみてみて(2023年7月)

Firebase連携アプリ、みてみてエストーク伊勢125社巡り

このうち、みてみてにフォーカスを当て、Firebaseのアクセス動向やアプリの改善を考察する開発記事です。

Realtime Database+Storage構成の投稿アプリ

まずはアプリのユーザー数の変動とともにFirebaseのアクセス動向を確認します。

2023年6月23日~2023年7月22日のユーザー数の変動

(ユーザー数の変動)

1ヶ月の新規獲得ユーザー数

前回のアプリ改修日が2023年5月4日。

それから約2ヶ月半、アプリの改修は停滞。

そして、ユーザー数は微減傾向。

その間もたまに使っているがアプリの遅延が気になるので抜本的な対策をとりたいところ。

(インストールの上位国)

フィリピン、インドネシアのインストールを維持。

アラブ首長国連邦、インドは期待。

2023年7月23日直近のFirebaseの変動

(Firebaseの変動)

直近のfirebaseの動き
1ヶ月のfirebase使用量

まだまだ微々たる使用量ですが安定してます。

2023年6月23日~2023年7月22日のAdMob

今月はAdMob広告収入:111円、 Firebase使用料:0円となりました。

今月のみてみて

(今月の投稿ピックアップ)

京都河原町でモンスターエナジーの先行無料配布

もう店頭にも並んでますね。

今後の改善案

(未消化の課題)

・アプリ起動処理の見直し

・チャット機能強化

・アプリUIブラッシュアップの継続

・フレンドグループ化と共有機能の追加

開発環境と本番環境を使い分ける

2023年6月3日

開発環境
OS:Windows 11
SDK:VS Code + flutter 3.7.5

概要

データベースを使ったアプリ開発で必要になってくるのが開発環境と本番環境の分離。

開発用データベースと本番用データベースをコマンドベースで使い分けます。

Firebase設定ファイル

Firebaseのアクセス制御は、CLIでFirebase設定を行った際に自動生成するオプションファイル、firebase_options.dartの定義に従い行われます。

import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
    show defaultTargetPlatform, kIsWeb, TargetPlatform;

class DefaultFirebaseOptions {
  static FirebaseOptions get currentPlatform {
    if (kIsWeb) {
      return web;
    }
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        return android;
      case TargetPlatform.iOS:
        return ios;
      case TargetPlatform.macOS:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for windows - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
      case TargetPlatform.windows:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for windows - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
      case TargetPlatform.linux:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for linux - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
      default:
        throw UnsupportedError(
          'DefaultFirebaseOptions are not supported for this platform.',
        );
    }
  }

  static const FirebaseOptions web = FirebaseOptions(
    apiKey: '***************',
    appId: '***************',
    messagingSenderId: '***************',
    projectId: '***************',
    authDomain: '***************',
    databaseURL: '***************',
    storageBucket: '***************',
    measurementId: '***************',
  );

  static const FirebaseOptions android = FirebaseOptions(
    ~
  );

  static const FirebaseOptions ios = FirebaseOptions(
    ~
  );
}

ファイルの中身は、android、iOS、Web、デスクトップアプリ用にそれぞれ下記の設定値が

定義されています。

apiKey
appId
messagingSenderId
projectId
authDomain
databaseURL
storageBucket
measurementId

これらの設定値は、特定のFirebaseプロジェクトを指し示すものであり、

開発用、本番用と2つのプロジェクトを用意した場合は

2つのオプションファイルを使い分ける必要があります。

定義

ステップ1)ファイル名を分け、オプションファイルを共存させる

2つのオプションファイルを使い分けるためにファイル名を変更し、同一フォルダ内で管理します。

そこでlibフォルダの直下にgenフォルダを作成し、オプションファイルを格納することにします。

開発用)lib/gen/firebase_option_dev.dart

本番用)lib/gen/firebase_option_prod.dart

ステップ2)ソースコードでFlavorを使い、参照ファイルを使い分ける

FirebaseのInitial処理で参照先のオプションを振り分けます。

Flavorは、実行時に入力するコマンドオプションであり、

実行時に入力した値に従い、プログラムが実行します。

import 'package:firebase_core/firebase_core.dart';
import 'package:sample/gen/firebase_options_dev.dart' as dev;
import 'package:sample/gen/firebase_options_prod.dart' as prod;

void main() async {
  await Firebase.initializeApp(
    options: options: getFirebaseOptions(),
  );  
  runApp(MyApp());
}

FirebaseOptions getFirebaseOptions() {
  const flavor = String.fromEnvironment('FLAVOR');
  switch (flavor) {
    case 'dev':
      return dev.DefaultFirebaseOptions.currentPlatform;
    case 'prod':
      return prod.DefaultFirebaseOptions.currentPlatform;
    default:
      throw ArgumentError('No flavor');
  }
}

上記ではクラス「DefaultFirebaseOptions」が開発と本番で共存するため、

オプションンファイルをimportする際に「as」定義行い、使い分けています。

これでFlavorの入力値により参照先のFirebaseプロジェクトを切り替えることができます。

これで定義は終了です。

Flavorを使い、実行する

あとは実行する際にコマンドラインでFlavorを指定します。

デバッグ時) 開発環境のFirebaseを使用する

flutter run -d (デバイスID) –dart-define=FLAVOR=dev

アプリ作成時) 本番環境のFirebaseを使用する

flutter build appbundle –dart-define=FLAVOR=prod

パッケージIDを開発と本番で分ける場合は更にAndroid Studio、及び、Xcodeの変更が必要となります。

今回は以上です。

Firebaseを使ってみる(Firestore編)

2023年5月27日

開発環境
OS:Windows 11
SDK:VS Code + flutter 3.7.5

概要

アプリを作るうえで欠かすことのできない存在であるデータベース。

Firebaseなら簡単で気軽に利用することができます。

今回はFirebaseでデータの参照、更新を行います。

Firestoreを更新する

Firebaseのセットアップが済んだら、flutterでFirestoreを更新してみます。

入力ボックスとボタンを用意し、ボタン押下時に入力ボックスに入力された文字を

Firestoreに登録する処理を必要部分だけ抜粋しました。

import 'package:firebase_database/firebase_database.dart';

 final strComment = TextEditingController();

 //入力ボックス
  TextField(         
    controller: strComment,             
    decoration: InputDecoration(
      hintStyle: const TextStyle(fontSize: 10),
      hintText: 'コメントを入力する'
    ),
    maxLines: 1,
    style: const TextStyle(fontSize: 10),
  )

  //ボタン
	ElevatedButton(
	  onPressed: () async {
	    await setComment(strComment.text);
	  }, 
	  child: Text('コメント更新')
	))

  //更新処理
  Future<void> setComment(String comment) async {
    DatabaseReference comRef = FirebaseDatabase.instance.ref('comment').child('sample');
    comRef.set(comment);
  }

Firestoreは、No SQLデータベースです。

上記は、ドキュメント「comment」のフィールド「sample」に入力値をセットしています。

Firestoreを参照する

参照処理も更新処理と同様、参照パスを定義し、そのリファレンスをゲットするだけです。


 final strComment = TextEditingController();

  //ボタン
	ElevatedButton(
	  onPressed: () async {
	    strComment.text = await getComment();
      setState((){});
	  }, 
	  child: Text('コメント参照')
	))

  //参照処理
  Future<String> getComment() async {
    var rtnval = "";  
    DatabaseReference dbRef = FirebaseDatabase.instance.ref('comment').child('sample');
    final snapshot = await dbRef.get();
    if (snapshot.exists) {
      rtnval = snapshot.value.toString();
    }
    return rtnval;
  }

今回は以上です。