今月のみてみて(2022年4月)

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

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

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

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

2022年4月1日~4月30日の新規獲得ユーザー数

(ユーザー数の変動)

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

先月と変わらず穏やかな波を描いていますが、直近2日ほど1日のインストール数が10人を超える日が続いているのでこの後の動向に注視したいところです。

ただし、ユーザー減少数の波とインストール数の波がシンクロしており、アプリの魅力を伝えられていないというのは相変わらず。

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

先月に引き続きフィリピン、インドネシアと続き、ロシアが再び、ランクイン。

リリース初期のインストール上位3ヵ国で継続してインストールしてもらっているようです。

そして、新たにブラジルがランクインです。

来月もインストール数が伸びるようなら多言語化対応としてポルトガル語を対応したいと思います。

(Firebaseの変動)

ようやくMBの領域になってきましたが、いかんせん投稿数が少ないのでなんとも言えないですね。

まだしばらくはFireBaseのアクセスに関して懸念すべき点はなさそうです。

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

各国の投稿を増やしたいとの思いで国旗を各国の
日本大使館近くに投稿してみました。

(今のところ反応は薄いです。。。

(今後の改善案)

基本的なコミュニケーション機能は一通り実装してみたのであとは如何に投稿してもらえるようにするかが考え所です。

①世界中の投稿数を増やす。

②UIの改善。

③ベースアーキテクチャのデファクタリング。

改善案として3点あげましたが、③は少し大掛かりになりそうなので、まずは①と②を少しずつ進めていこうと思います。

,

ファミリーポリシーを遵守するためのAdmob設定

概要

ヒットアンドブローを題材にしたミニゲーム”サムライロード”、
このアプリは対象年齢を10歳以上としており、ファミリーポリシーの遵守が必須です。

そのため、Admobのイニシャル処理とリクエスト処理に子供向け設定を入れていたのですが、アプリの更新審査のタイミングでファミリーポリシー違反となりました。
(ファミリーポリシーを遵守するためのAdmobコーディングについてはこちらの記事。)

なぜ?

Admobの配信カテゴリを設定する

アプリの更新審査に落ちた理由がこちらです。

審査結果通知

Admobから配信されている広告に子供にふさわしくないコンテンツが含まれていた、とのこと。

テレビ、動画、音楽、その他情報配信系の広告を表示するとファミリーポリシー違反となるようです。

そこで、Admob側の設定を変更することにしました。

Google Admob コンソール

まずはGoogle Admobコンソールを表示して広告配信を制御したいアプリを選びます。
そして、メニューの「ブロックのコントロール」を選択。

Google Admob コンソール

次に一般カテゴリを選択し、ふさわしくないと指摘されたテレビ、動画、音楽の配信をブロックしました。

あとは、再審査を促すため、バージョンのみを変更したアプリを再リリース。

再審査の結果、合格となりました。

今月のみてみて(2022年3月)

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

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

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

2022年2月21日~3月22日の変動

アプリのユーザー数の変動とともにFirebaseの動きを確認します。

(ユーザー数の変動)

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

今月も大きな動きはありません。

OUTよりINが多いのがせめてもの救い。

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

引き続きフィリピン、インドネシアが上位となっています。

そして、新たにコロンビア、サウジアラビア、香港がランクインしました。

前回は上位3か国(フィリピン、インドネシア、ロシア)のユーザーへのアプローチとして、インドネシア語、ロシア語の多言語化に取り組みました。
(フィリピンは英語が公用語となっているため、対応済み)

残念ながらロシアへのアプローチは失敗したようです。

今回の多言語化は保留です。

(Firebaseの変動)

今月もユーザー数の伸びがないため、想定内の緩やかな変動となっています。

無料プランで維持できる状況です。

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

ポケモンのマンホールが伊勢に設置されました!
ポケストップができるのが待ち遠しい。

投稿がないので自身の投稿です。(^^;

(今後の改善案)

前回挙げておいて対応できなかったコミュニケーション機能の追加。

これをなんとか入れたい。

あとは投稿がないなら、まずは自身で投稿してみよう!

ということで世界各地に幾つか投稿してみます。

何を投稿するか?となると写真などは著作権の問題もある。

となると投稿するならあれでしょうか。

世界情勢もあるのでそこも訴えたいですね。

,

Googleマップが表示されない事象の発生から解決まで

概要

2022年3月9日早朝、自作アプリ“みてみて”を起動したところ、Googleマップが表示されないことに気付く。

慌ててGoogleマップを使用している自作アプリを片っ端から起動した結果、全滅でした。

なぜGoogleマップが表示されなくなったのか?

事象の発生から解決までの道のりを記事にしました。

Noアプリ名事象発生当時の最終リリース日
みてみて2022年2月24日
伊勢125社巡り2022年2月5日
伊勢テイクアウトなび2020年6月4日
みまもってね2022年1月15日
Googleマップが表示されなくなったアプリ一覧
伊勢125社巡り
マップ表示(改修前)
みてみて
マップ表示(改修前)

Googleマップの実装

最初に自作アプリにGoogleマップをどう実装しているかをざっくり説明します。

まず始めにデフォルトのMapsActivityを追加します。

ただし、そのままだとフラグメントのみの構成のため、ConstraintLayoutに組み込むようレイアウトを変更します。

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/constraint_map">
        <fragment
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

Activity側のベースロジックは変更しません。

あとはGoogle Cloud Platformでプロジェクトを作成し、APIの有効化でMaps SDK for Androidを選択。

APIキーを入手後、AndroidManifest.xmlのメタデータにAPIキーを定義します。

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="MAP_API_KEY" />

最後にMapsActivityのタイトルを非表示にするため、Activityにスタイルを設定して完成です。

マップ表示は基本的に”com.google.android.gms.maps.SupportMapFragment”まかせの処理としています。

突然Googleマップが表示されなくなった

自作アプリは随時、改修を行っています。

今回問題が発生したアプリも2022年2月24日に改修してリリースしたものがありました。

もちろんリリース前に動作確認しており、そのときにはマップ表示に問題がなかったのです。

それから約2週間後、突然Googleマップが表示されなくなりました。

つまりアプリに手を加えていないタイミングでマップが表示されなくなったということです。

そうなるとまずはアプリ内部の処理ではなく外部を疑いたくなるものです。

解決までの道のり

まず疑ったのはマップデータが受け取れてないのでは?ということです。

GoogleマップAPIが使えなくなっていないか?

Google Clound Platformでプロジェクトの設定やAPIキーの制限を確認しますが問題ありませんでした。

次にGoogleマップの表示だけを行うサンプルアプリを作成し、APIキーを使ってみます。

するとGoogleマップが表示されました。

GoogleマップAPIは正常に機能していたわけです。

確かにGoogle Clound PlatformでAPIのトラフィックを確認するとアプリではマップが表示されてないにも関わらず、データ通信は発生していました。

伊勢125社巡りのAPI(Map SDK for Android)のトラフィック

マップデータは受け取れている。となると次はアプリ内部の処理を疑わざるおえません。

アプリをデバッグモードで起動し、試しにデフォルトのMapsActivityを追加してみます。

そして、アプリを動かしてみると。。。

デフォルトのMapsActivityにGoogleマップが表示されました。

そうなるとデフォルトのMapsActivityと作り込んだMapsActivityの違いを調べるだけです。

デフォルトのMapsActivityにコードを徐々に追加し、マップが表示されなくなるか確認。

なんと最後までGoogleマップは表示されました。

つまり、MapsActivityのコード内容には問題がなかったわけです。

あと違いがあるのは何か?

ここでスタイル設定に気が付きます。

デフォルトのMapsActivityにタイトル非表示用に定義したスタイルを設定してみると。。。

Googleマップが表示されなくなりました。

そう、原因はスタイル定義だったんです。

ちなみに問題となったスタイルが以下です。

    <style name="AppTheme.NoTitleStatus" parent="@style/Theme.AppCompat.NoActionBar">
        <item name="android:background">@color/colorBackground</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">false</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowIsTranslucent">true</item>
    </style>

このなかで問題を引き起こしたのがバックグランド設定でした。

事象から察するにマップフラグメントがバックグランドの裏に隠れるようになったのではないでしょうか。

今回の改修案としてはバッググランド設定を透明に変更したスタイルを新たに用意。

それをMaspActivityに設定することで解決しました。

それにしてもまさかアプリ内部処理が要因だったとは・・・

伊勢125社巡り
マップ表示(改修後)
みてみて
マップ表示(改修後)

後書き

今回の件で一番驚いたのはアプリ内のライブラリのバージョンを上げたり、コードを変更したりすることなく、Googleマップが表示されなくなったことです。

アプリの更新を行わずにアプリの挙動が変わるとは思っていなかったため、最初は外部要因(マップAPIのIF依存)だとばかり思っていました。

結局、今回の事象の真の要因は何かは分からないですが、アプリ自体を更新しなくてもアプリの挙動が変わってしまうことがあるというのは勉強になりました。

ファミリーポリシーを遵守するためのAdMobコーディング

概要

Google Playでアプリをリリースする際に設定するアプリの対象年齢(ターゲットユーザー)。

今回はアプリの対象年齢に13歳未満を含める場合に必要となるAdMobのコーディングについて記事にしました。

AdMobに子供向け広告をリクエストする

GooglePlayで設定するアプリの対象年齢は以下のように分かれています。

No対象年齢ファミリー向けプログラム
15歳以下必須
26~8歳必須
39~12歳必須
413~15歳任意
516~17歳任意
618歳以上任意
ターゲットユーザー設定

ターゲットユーザーの設定としては13歳以上か、13歳未満かが大きな分岐点となります。

なぜなら13歳未満をターゲットに含める場合は

ファミリーポリシーを遵守するために子供向けの広告を表示することが求められるからです。

では、子供向けの広告を表示するにはどうすればよいのか?

Admobのヘルプを調べると下記のコードが示されていました。

Bundle extras = new Bundle();
extras.putString("max_ad_content_rating", "G");
AdRequest request = new AdRequest.Builder()
 .addNetworkExtrasBundle(AdMobAdapter.class, extras)
 .tagForChildDirectedTreatment(true) .build();

ただし、これを実際にコーディングしようとしても

tagForChildDirectedTreatmentメソッドが見つかりません

どうしたものかとネット検索してみた結果、タグ指定はイニシャル処理にあわせて実行するのがよさそうだという結論に至りました。

通常のAdMobイニシャル処理

MobileAds.initialize(this)

子供向けのAdMobイニシャル処理

val requestConfiguration = MobileAds.getRequestConfiguration().toBuilder()
    .setTagForChildDirectedTreatment(TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE)
    .setMaxAdContentRating(MAX_AD_CONTENT_RATING_G)
    .build()
MobileAds.setRequestConfiguration(requestConfiguration)
MobileAds.initialize(this)

子供向けに実装する場合は、イニシャル処理の前に子供向けタグとレーティングGを設定します。

また、AdMob表示のための広告リクエストでもレーティングGを設定しておきます。

通常のバナー広告リクエストと表示処理

val adView : AdView = findViewById(R.id.adView)
val adRequest = AdRequest.Builder().build()
adView.loadAd(adRequest)

子供向けのバナー広告リクエストと表示処理

val adView : AdView = findViewById(R.id.adView)
val extras = Bundle()
extras.putString("max_ad_content_rating", "G")
val adRequest = AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter::class.java, extras).build()
adView.loadAd(adRequest)

通常のリクエストにレーティング設定を追加すればOKです。

Admobから配信されるカテゴリを制御する方法は以下の記事を参照ください。

今月のみてみて(2022年2月)

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

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

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

2022年2月1日~2月14日の変動

アプリのユーザー数の変動とともにFirebaseの動きを確認します。

(ユーザー数の変動)

微小ながらインストール数は伸びていますが、次に繋がる動きにはなっていません。

インストール、アンインストールの波を見るに小さなコミュニティで話題になったものの興味を引くことはできなかったということでしょうか。

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

インストールの上位国を見ると実際に投稿を頂けている国が上位になっています。

ただ、今のところ、ロシア、フランスからの投稿はありません。

アプリが日本語、英語のみに対応している影響かもしれないと思うと多言語化するか悩みどころです。

(Firebaseの変動)

100人を超えない程度のユーザー数なのでRealtime DatabaseはKB単位での変動となっています。

また、Storageにおいても投稿数が伸びないこともあり、10MBに届かない範囲での変更です。

まだまだ無料プランで維持できる状況となっています。

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

フィリピンから空港の模様を投稿してもらえました。人がいないのはコロナの影響でしょうか?
投稿ありがとうございます。

(今後の改善案)

ユーザー数の減少を回避するための改善として以下の2点を強化予定。

・最近追加したコメント機能の強化。

・ユーザー間のコミュニケーション機能の追加。

まずは上記2点の改善を追加し、動きを見たいと思います。

,

日付のソートが失敗していた話

概要

型変換の認識不足により日付のソートに失敗しておりました。

Long型とInt型、型変換する際は気を付けねば、という話です。

2022年の投稿がソートで正しく表示されないバグ

投稿アプリ「みてみて」には全ての投稿をリスト表示する画面があります。

このリストでは新着順、いいね順、距離順の3パターンでソートできるようにしているのですが。。。

2022年の最新の投稿を新着順でソートした際に先頭に表示されないバグが発覚。

ロジックを見直しても一見、おかしなところも見当たらず。

そこでソートロジックを切り取り、テストアプリを作成してログを確認。

ようやく理由が判明した、というわけです。

日付をソートするテストアプリで動作確認

まずは適当に日付をセットしたリストを用意し、表示するだけのアプリを作成。

これにソート用のボタンを追加し、ボタンをタップするとソートしてリスト表示を反映させるロジックを追加。

        val btnUp = findViewById<Button>(R.id.btnUp)
        btnUp.setOnClickListener {
            Collections.sort(list, object : Comparator<List>{
                override fun compare(p0: List?, p1: List?): Int {
                    val tmpdiff = p1!!.timestamp - p0!!.timestamp
                    return tmpdiff.toInt()
                }
            })
            adapter.setList(list)
            adapter.notifyDataSetChanged()
        }

上記はアプリに組み込んだロジックを切り取ったものですが間違いに気づきましたでしょうか?

日付はLong型(1970年1月1日00:00を起点とした経過時間)で扱っています。

ソートはCollections.sortのcompareメソッドを使用。

compareは大小比較さえできればよいだろうということでLong型の差分をリターンすればよいと判断。

ただし、それだとInt型で受けれないのでLong型からInt型に型変換を追加。

そして、このロジックでソートした結果が以下となります。

ソートされていません。

ここでログを仕込み、引数1、引数2、引数2と引数1の差分(Long型)、差分の型変換(Int型)の順で出力してみると。

Long型では負なのに、Int型では正になっていることが発覚。

Long型は8バイト、Int型は4バイト。

上記で1例を見るとLong型の値、-2678400000は16進数で0xFFFF FFFF 605A DC00。

これをInt型に変換すると先頭4バイトが落ち、16進数で0x605A DC00。

つまり、1616567296。正の値になりました。

Int型への型変換で4バイトの情報だけを参照した結果、正の領域が負の領域に切り替わってしまったというわけです。

正しいロジックとは

修正するとすれば2パターンでしょうか。

パターン1)Date型に変換し比較する。

        val btnUp = findViewById<Button>(R.id.btnUp)
        btnUp.setOnClickListener {
            Collections.sort(list, object : Comparator<List>{
                override fun compare(p0: List?, p1: List?): Int {
                    val datea = Date(p0!!.timestamp)
                    val dateb = Date(p1!!.timestamp)
                    return dateb.compareTo(datea)
                }
            })
            adapter.setDateList(list)
            adapter.notifyDataSetChanged()
        }

パターン2)Long型の差分結果をもとにInt型で正負に置き換える

        val btnUp = findViewById<Button>(R.id.btnUp)
        btnUp.setOnClickListener {
            Collections.sort(list, object : Comparator<List>{
                override fun compare(p0: List?, p1: List?): Int {
                    val tmpdiff = p1!!.timestamp - p0!!.timestamp
                    var rtnval = 0
                    if (tmpdiff < 0L) {
                        rtnval = -1
                    } else if (tmpdiff == 0L){
                        rtnval = 0
                    } else {
                        rtnval = 1
                    }
                    return rtnval
                }
            })
            adapter.setDateList(list)
            adapter.notifyDataSetChanged()
        }

どちらのロジックにしろ、正しくソートされました。

早速、修正したいと思います。

APIキー定義をプロジェクト外部で管理する

概要

少し前にandroidアプリをリリースしようとしたところ、

Google Play Consoleで警告を出されたので記事にしておきます。

APIキーの定義は慎重に

アプリに外部サービス(YouTubeやGoogle Mapなど)を組み込む場合、必ずAPIキーが必要になると思います。

APIキー(文字列)をどのように管理しますか?

私はstring.xmlに定義していました。

この管理方法に対し警告が出されたわけです。

外部サービスは基本的に従量課金制です。

一定量まで無料、それ以上はサービス使用量に応じて課金されます。

外部サービスにアクセスする際に使用されるAPIキーは言わばユーザーアカウント。

APIキーに紐づくユーザーにサービス使用量が加算されるわけです。

そのAPIキーをstring.xmlに定義するとどうなるか?

簡単なアプリ解析でバレてしまうようです。。。

APIキーが漏洩してしまうとそれを悪用してサービスのタダ乗りをされてしまうよ!

ということで警告を出されたのでした。

うかつでした。。。

APIキーを隠匿する2つの方法

APIキーをどのように管理すればいいのか。

APIキーをプロジェクト外部に定義し、プロジェクト起動時にメモリ(変数)に保持させるのがいいようです。

そして、その方法は2つ。

環境変数に定義する方法と外部ファイルに定義方法です。

外部管理方法その1.環境変数に定義する

(1)まずは環境変数にAPIキーをセットします。

コマンドライン操作を使った環境変数の設定方法はこちらを参照してください。

(2)次にbuild.gradle(app)に環境変数の参照処理を定義します。

    defaultConfig {
        minSdk 24
        targetSdk 31
        versionCode 1
        versionName "1.0"

        manifestPlaceholders = [KEY_VALUE: System.getenv("api_key")]
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

上記は環境変数”api_key”の値を変数”KEY_VALUE”に格納しています。

(3)次にAndroidManifest.xmlの定義です。

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"

        <meta-data
            android:name="API_KEY"
            android:value="${KEY_VALUE}" />

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

プロジェクト内で参照できるようメタデータに格納します。

(4)あとは参照するだけです。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val appInfo = getPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA)
        val apiKey = appInfo.metaData.getString("API_KEY")

        val txtSet = findViewById<TextView>(R.id.txtSet)
        txtSet.setText(apiKey)
    }
}

上記では取得した環境変数をテキストに表示させています。

外部管理方法その2.外部ファイルに定義する

(1)まずは定義ファイルを作成します。

ファイル名に任意ですがファイルの格納場所は以下です。

debugとreleaseの2か所に格納します。ファイルは全く同じもので問題ありません。

赤枠の場所にファイルを格納します。

ファイルの格納パス

C:\~\AndroidStudioProjects\プロジェクト名\app\src\release\res\values\

C:\ ~ \AndroidStudioProjects\ プロジェクト名 \app\src\debug\res\values\

定義ファイル

<resources>
    <string name="api_key" templateMergeStrategy="preserve" translatable="false">APIキー</string>
</resources>

上記の”APIキー”の箇所に実際のAPIキーを定義します。

(2) 次にAndroidManifest.xmlの定義です。

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"

        <meta-data
            android:name="API_KEY"
            android:value="@string/api_key" />

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

プロジェクト内で参照できるようメタデータに格納します。

(3)あとは参照するだけです。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val appInfo = getPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA)
        val apiKey = appInfo.metaData.getString("API_KEY")

        val txtSet = findViewById<TextView>(R.id.txtSet)
        txtSet.setText(apiKey)
    }
}

以上がAPIキーの外部管理方法です。

APIキーのstring.xml定義はくれぐれもご注意ください。

,

バッチファイルを使う

概要

バッチファイルの役割からWindows環境でのバッチファイルの使い方までをまとめました。

コマンドライン操作

基本的にWindowsで何か作業をする場合、

例えばフォルダを作る、ファイルをコピーする、環境変数を設定する、など。

マウスを使い、アイコンをクリック、メニューを表示して、とGUI操作で作業すると思います。

しかし、パソコンを操作する手段はもう1つ用意されています。

それがコマンドライン操作です。

ますはコマンドプロンプトを起動。
(Winキー+Rで「ファイル名を指定して実行」を表示、”cmd” と入力で起動します。)

コマンドプロンプトにコマンドを入力するとGUI操作と同様のことが行えます。

例えばフォルダを作る。

コマンドプロンプトに”mkdir work”と入力します。

そうすると”work”という名前のフォルダが作成されます。

以下は一般的なコマンド一覧です。

Noコマンド処理内容
dirフォルダに格納されたファイルリスト表示
mkdirフォルダ作成
cd フォルダ移動
renファイル名変更
delファイル削除
copyファイルコピー
7typeファイルのテキスト表示
8set環境変数設定
9d:Dドライブに移動
10exitコマンドプロンプト終了

バッチファイルの役割

コマンド入力で操作をしていると繰り返し同じコマンドの流れを入力するときがあると思います。

そのようなときに活躍するのがバッチファイルです。

実行したいコマンドの流れをテキストファイルに書き出して拡張子を.batとして保存。

コマンドラインに保存したバッチファイルのファイル名を入力。

するとテキストファイルに書き出したコマンドが順次実行されます。

バッチファイルの実行はファイルのアイコンをダブルクリックするだけでもOKです。

それならコマンドを知らない人でも容易にコマンドライン操作が実行できるわけです。

バッチファイルを作成することはコマンド入力の簡素化や誰でもコマンドライン操作ができるようになるというメリットがあります。

例えばプログラムの開発環境を作成するために環境変数を設定する。

そのようなときはバッチファイルを作成し、、グループで共有すれば共通の環境を作成することができます。

バッチファイルの中身

環境変数を設定する場合、バッチファイルの記載内容は以下です。

set WORK=testvalue

上記では変数名”WORK”に”testvalue”を設定しています。

また、Windows10の場合はsetxコマンドを使います。

setx WORK testvalue

環境変数にはユーザー環境変数とシステム環境変数がありますが上記はユーザー環境変数に設定するコマンドです。

また、コマンド実行後はパソコンを再起動しないと反映されません。

,

今週のFirebase

2022年1月11日~1月17日のFirebase使用状況

さて、今週のFirebaseの使用状況はどうだったでしょうか?

アプリのユーザー数の変動とともに確認します。

みてみて

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

(ユーザー数の変動)

興味本位でインストールして頂けているようですが定着せず。

まずはUIの改善を早めにいれたいところです。

(Firebaseの変動)

インストールに伴うユニークID登録の影響でRealtime Databaseが微増。

投稿に伴うStorageの変動は確認できず。

エストーク

Realtime Database単体構成のチャットアプリ

(ユーザー数の変動)

こちらもみてみて同様、インストールされているものの定着せず。

(Firebaseの変動)

インストールに伴うユニークID登録の影響でストレージが微増。

オンラインチャットが使われだすとDLサイズももっと伸びてくると思うのですが

まだその影響を見ることはなさそうです。

,