firebase functionsにデプロイした関数をテストするたびに

firebase deploy –only functions

を実行し、デプロイが完了するまで待つのは大変時間がかかるので、基本的には

firebase emulators:start

でローカル環境で実行する。

データベース接続処理などを行う場合、一般的にはfirebaseの環境変数に

firebase functions:config:set database_password=”*****”

等でコンソールから保存した内容をコード上で

functions.config().database_passwordといった具合で参照するが、これは本番環境でしか使用できない。

したがってエミュレーターでローカルでテストしたい場合には別途.envファイルをfunctionsフォルダ内に作成してテスト環境用に別のコードで.envを参照していたが、画期的な方法があったのでメモ

firebase functions:config:get > .runtimeconfig.json

上記コマンドを実行することで、firebase functionsに保存していた環境変数がローカルのカレントディレクトリに.runtimeconfig.jsonというファイルで保存される。

そしてfirebase emulators:start –import=.runtimeconfig.jsonでエミュレーターを実行することにより、本番環境と同じコードで環境変数を参照することができる。

“https://androidpublisher.googleapis.com/androidpublisher/v3/applications”エンドポイントを使用して、ユーザーが購入したサブスクリプションの期限を調べようとしたら、

{

     "message": "The current user has insufficient permissions to perform the requested operation.",
     "domain": "androidpublisher",
     "reason": "permissionDenied"
   }

が発生し続けた。

GCPやPlay console上でもサービスアカウントに必要な権限は全て付与したつもりでいたが、原因がわかったのでメモ

原因はこのサービスアカウントを設定するよりも先にアプリ内課金アイテム(今回の場合は定期購入)をプレイストア上で作成してしまっていたこと。

この場合は何でもいいのでアイテムに変更を加えないといけないらしい。適当に名前など一部情報を変更して更新したところ、permissionDeniedが解消され、無事必要なデータをGoogle Develope APIを通して取得できた。

open -a Simulator

いままでxcodeを開いて、メニューからシミュレーターを起動していたが直接Simulatorを起動できたので備忘録。

emulator -avd Pixel_6a

Pixel_6aはインストール済みのエミュレーター名

インストール済みのエミュレーターは以下のコマンドで確認

adb devices

adbコマンドがインストールされていない場合はAndroid Studio SDKのパスが通っているか確認

通常は

/Users/AndroidSDK/platform-tools

等のPATHを通す

Flutterでプロジェクトを作成

flutter create --platforms=android,ios my_project

XCodeでios/Runner.xcworkspaceを開きProduct>Archiveを実行しStore Connectにアップロード

Store Connectで色々設定して審査

関数とは、呼び出されたときにのみ実行されるコードのブロックです。

関数にはデータ(パラメータ/引数)を渡すことができます。

関数は特定のアクションを実行するために使用され、メソッドとも呼ばれます。

目次 [表示]

組み込み関数

関数は既にほかの章で使われていたので、なんとなくどんなものかは既におわかりいただけているかもしれません。

例えば、println() は関数です。これはテキストを画面に出力するために使用されます:

fun main() {
  println("Hello World")
}

自分の関数を作成する

自分の関数を作成するには、fun キーワードを使用し、関数の名前を書いた後に括弧 () を続けます:

fun myFunction() {
  println("I just got executed!")
}

関数の呼び出し

関数を作成したら、それを呼び出して実行することができます。

Kotlinで関数を呼び出すには、関数の名前の後に括弧 () を書きます。

以下の例では、myFunction() が呼び出されると、テキスト(アクション)が出力されます:

fun main() {
  myFunction() // myFunctionを呼び出す
}

// 出力: "I just got executed!" 

関数は複数回呼び出すことができます:

fun main() {
  myFunction()
  myFunction()
  myFunction()
}

// 出力:
// I just got executed!
// I just got executed!
// I just got executed! 

関数のパラメータ

関数に情報をパラメータとして渡すことができます。

パラメータは関数名の後、括弧内に指定します。複数のパラメータをカンマで区切って追加できます。ただし、各パラメータの型(Int、String など)を指定する必要があります。

以下の例では、fname という名前の String 型のパラメータを取る関数があります。関数が呼び出されると、名前を渡してフルネームを出力します:

fun myFunction(fname: String) {
  println(fname + " Doe")
}

fun main() {
  myFunction("John")
  myFunction("Jane")
  myFunction("George")
}

// 出力:
// John Doe
// Jane Doe
// George Doe 

パラメータが関数に渡されると、それを引数と呼びます。上記の例では、fname がパラメータであり、John、Jane、George が引数です。

複数のパラメータ

必要に応じて複数のパラメータを指定できます:

fun myFunction(fname: String, age: Int) {
  println(fname + " is " + age)
}

fun main() {
  myFunction("John", 35)
  myFunction("Jane", 32)
  myFunction("George", 15)
}

// 出力:
// John is 35
// Jane is 32
// George is 15 

注意:複数のパラメータを使用する場合、関数呼び出しで引数の数はパラメータの数と同じでなければならず、引数は同じ順序で渡す必要があります。

戻り値

上記の例では、関数を使用して値を出力しました。以下の例では、関数を使用して値を返し、その値を変数に代入します。

値を返すには、return キーワードを使用し、関数の括弧の後に戻り値の型を指定します(この例では Int):

fun myFunction(x: Int): Int {
  return (x + 5)
}

fun main() {
  var result = myFunction(3)
  println(result)
}

// 出力: 8 (3 + 5) 

2つのパラメータを使用する例:

fun myFunction(x: Int, y: Int): Int {
  return (x + y)
}

fun main() {
  var result = myFunction(3, 5)
  println(result)
}

// 出力: 8 (3 + 5) 

戻り値の短縮文法

戻り値を返すための短縮文法もあります。戻り値の型を指定せずに = 演算子を使用することができます。Kotlin は自動的に型を推測します:

fun myFunction(x: Int, y: Int) = x + y

fun main() {
  var result = myFunction(3, 5)
  println(result)
}

// 出力: 8 (3 + 5) 

forループを使用すると、範囲を指定して値を作成することもできます。範囲は「..」を使用して作成します:

目次 [表示]

for (chars in 'a'..'x') {
  println(chars)
}

数字の範囲も作成できます:

for (nums in 5..15) {
  println(nums)
}

注意:範囲には最初と最後の値が含まれます。

値の存在を確認する

値が範囲に存在するかどうかを確認するには、in 演算子を使用できます:

val nums = arrayOf(2, 4, 6, 8)
if (2 in nums) {
  println("存在します!")
} else {
  println("存在しません。")
}

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")
if ("Volvo" in cars) {
  println("存在します!")
} else {
  println("存在しません。")
}

範囲でのブレークまたはコンティニュー

範囲/forループで breakcontinue キーワードを使用することもできます:

for (nums in 5..15) {
  if (nums == 10) {
    break
  }
  println(nums)
}

for (nums in 5..15) {
  if (nums == 10) {
    continue
  }
  println(nums)
}

配列を扱うときに、すべての要素をループ処理する必要があることがよくあります。

配列の要素をループ処理するには、for ループと in 演算子を組み合わせて使用します:

目次 [表示]

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")
for (x in cars) {
  println(x)
}

すべての種類の配列をループ処理することができます。上記の例では文字列の配列を使用しました。

以下の例では、整数の配列をループ処理しています:

val nums = arrayOf(1, 5, 10, 15, 20)
for (x in nums) {
  println(x)
}

従来のforループ

Javaや他のプログラミング言語とは異なり、Kotlinには従来のforループは存在しません。

Kotlinでは、for ループを使用して、配列、範囲、またはカウント可能な値を含む他のものをループ処理します。

配列は、複数の値を1つの変数に格納するために使用されます。各値のために別々の変数を作成する代わりに、配列を使用します。

目次 [表示]

配列の作成

配列を作成するには、arrayOf() 関数を使用し、その中にカンマ区切りの値を置きます:

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")

配列の要素にアクセスする

配列の要素には、インデックス番号を指定してアクセスできます。インデックスは角括弧内に記述します。

この例では、cars 配列の最初の要素の値にアクセスします:

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")
println(cars[0])
// Outputs Volvo

注:文字列と同様に、配列のインデックスは0から始まります:[0]が最初の要素、[1]が2番目の要素、などです。

配列の要素を変更する

特定の要素の値を変更するには、インデックス番号を指定します:

cars[0] = "Opel"

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")
cars[0] = "Opel"
println(cars[0])
// Now outputs Opel instead of Volvo

配列の長さ / サイズ

配列にいくつの要素が含まれているかを調べるには、size プロパティを使用します:

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")
println(cars.size)
// Outputs 4

要素の存在を確認する

in 演算子を使用して、配列に要素が存在するかどうかを確認できます:

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")
if ("Volvo" in cars) {
  println("It exists!")
} else {
  println("It does not exist.")
}

配列をループする

配列を扱うときには、すべての要素をループする必要があることがよくあります。for ループを使用して配列の要素をループできます。次の章でさらに詳しく学ぶことができます。

以下の例では、cars 配列のすべての要素を出力します:

val cars = arrayOf("Volvo", "BMW", "Ford", "Mazda")
for (x in cars) {
  println(x)
}

目次 [表示]

break

breakステートメントは、ループから抜け出すために使用します。

以下の例では、iが4と等しいときにループから抜け出します:

var i = 0
while (i < 10) {
  println(i)
  i++
  if (i == 4) {
    break
  }
}

continue

continueステートメントは、指定された条件が発生した場合に、ループの現在の反復をスキップし、次の反復に進みます。

以下の例では、値が4のときにスキップします:

var i = 0
while (i < 10) {
  if (i == 4) {
    i++
    continue
  }
  println(i)
  i++
}