Ionic(Angular)でtabとサイドバーを備えたプロジェクトを作成する

概要

上記の画像のようなサイドメニューとタブバーを備えたプロジェクトを作成します。

流れ

IonicのデフォルトテンプレートのひとつであるTabプロジェクトにサイドメニューを追加します。

参考文献

https://petercoding.com/ionic/2019/05/05/side-menu-in-ionic4/

https://ionicframework.com/jp/docs/api/menu

準備 デフォルトのプロジェクトを作成する

下記のコマンドを打ってTabバーを備えたプロジェクトを生成します。

% ionic start sidemanu tabs --type=angular

さらにCapacitorを入れますか?(Integrate your new app with Capacitor to target native iOS and Android?) と聞かれたら、スマホアプリにすることを検討指定場合はYESにしておきます。

その後、作成したプロジェクトへ移動します。

$ cd sidemanu

プロジェクトへ移動したあと、下記コマンドで一度起動してみます。

ionic serve

このような画面が立ち上がればOKです。なお、デフォルトがIEなどのブラウザになっているとそもそも表示されないです。ChromeやEdgeでアクセスしてください。

なお、Tabバーのプロジェクト構成は下記となっています。

.
├── app-routing.module.ts
├── app.component.html
├── app.component.scss
├── app.component.spec.ts
├── app.component.ts
├── app.module.ts
├── explore-container
│   ├── explore-container.component.html
│   ├── explore-container.component.scss
│   ├── explore-container.component.spec.ts
│   ├── explore-container.component.ts
│   └── explore-container.module.ts
├── tab1
│   ├── tab1-routing.module.ts
│   ├── tab1.module.ts
│   ├── tab1.page.html
│   ├── tab1.page.scss
│   ├── tab1.page.spec.ts
│   └── tab1.page.ts
├── tab2
│   ├── tab2-routing.module.ts
│   ├── tab2.module.ts
│   ├── tab2.page.html
│   ├── tab2.page.scss
│   ├── tab2.page.spec.ts
│   └── tab2.page.ts
├── tab3
│   ├── tab3-routing.module.ts
│   ├── tab3.module.ts
│   ├── tab3.page.html
│   ├── tab3.page.scss
│   ├── tab3.page.spec.ts
│   └── tab3.page.ts
└── tabs
    ├── tabs-routing.module.ts
    ├── tabs.module.ts
    ├── tabs.page.html
    ├── tabs.page.scss
    ├── tabs.page.spec.ts
    └── tabs.page.ts

これにサイドメニューを設置して行きます

サイドバーに配置するページを作成しておく

事前にサイドメニューに設置するページを作成しておきます。新しいターミナルを立ち上げてプロジェクトフォルダまで移動したあと、下記コマンドでpageを2つ追加します。

ionic generate page side/mySide1
ionic generate page side/mySide2

プロジェクトは下記のようになります。

.
├── app-routing.module.ts
├── app.component.html
├── app.component.scss
├── app.component.spec.ts
├── app.component.ts
├── app.module.ts
├── explore-container
│   ├── explore-container.component.html
│   ├── explore-container.component.scss
│   ├── explore-container.component.spec.ts
│   ├── explore-container.component.ts
│   └── explore-container.module.ts
├── side
│   ├── my-side1
│   │   ├── my-side1-routing.module.ts
│   │   ├── my-side1.module.ts
│   │   ├── my-side1.page.html
│   │   ├── my-side1.page.scss
│   │   ├── my-side1.page.spec.ts
│   │   └── my-side1.page.ts
│   └── my-side2
│       ├── my-side2-routing.module.ts
│       ├── my-side2.module.ts
│       ├── my-side2.page.html
│       ├── my-side2.page.scss
│       ├── my-side2.page.spec.ts
│       └── my-side2.page.ts
├── tab1
│   ├── tab1-routing.module.ts
│   ├── tab1.module.ts
│   ├── tab1.page.html
│   ├── tab1.page.scss
│   ├── tab1.page.spec.ts
│   └── tab1.page.ts
├── tab2
│   ├── tab2-routing.module.ts
│   ├── tab2.module.ts
│   ├── tab2.page.html
│   ├── tab2.page.scss
│   ├── tab2.page.spec.ts
│   └── tab2.page.ts
├── tab3
│   ├── tab3-routing.module.ts
│   ├── tab3.module.ts
│   ├── tab3.page.html
│   ├── tab3.page.scss
│   ├── tab3.page.spec.ts
│   └── tab3.page.ts
└── tabs
    ├── tabs-routing.module.ts
    ├── tabs.module.ts
    ├── tabs.page.html
    ├── tabs.page.scss
    ├── tabs.page.spec.ts
    └── tabs.page.ts

以上で準備は完了です。あとはこの2つのページへハンバーガメニューからアクセスできるようにします。

サイドメニューを設置

app.component.htmlでサイドメニューを作成し、ion-router-outletに登録する

Ionicは、サイドメニューを簡単に作成するためにion-menuと呼ばれるコンポーネントを提供しています。app.coponent.htmlの中にion-menuタグを使ってサイドメニューを作っておいて、それを<ion-router-outlet>の中でidで紐付けます。ion-router-outletタグはコンポーネントを埋め込むために使用するものですので、これに登録しておくと作成したサイドメニューを他のページから簡単に読み込むことができるようになります。

最初はapp.component.htmlは下記のようになっています。ion-router-outletタグに何も登録がありません。

<ion-app>
  <ion-router-outlet></ion-router-outlet>
</ion-app>

これを下記のようにします。

<ion-app>
    <ion-menu side="start" menuId="first" contentId="my-content">
    '''
    '''
    </ion-menu>
  <ion-router-outdlet id="my-content"></ion-router-outlet>
</ion-app>

こうすることにより、ion-menuタグの中に設定した中身を他のページから読み込むことができるようになります。私の場合、下記のように設定しました。

<ion-app>
    <ion-menu side="start" menuId="first" contentId="content1">
        <ion-header>
          <ion-toolbar>
            <ion-title>Navigate</ion-title>
          </ion-toolbar>
        </ion-header>
        <ion-content>

          <ion-list lines="none">
            <ion-list-header>
              一般情報
            </ion-list-header>

            <ion-menu-toggle autoHide="false">
              <ion-item routerLink="/my-side1" routerLinkActive="active" routerDirection="root" detail="false">
                <ion-icon slot="start" name="person"></ion-icon>
                <ion-label>
                  Privacy Policy
                </ion-label>
              </ion-item>
            </ion-menu-toggle>

            <ion-menu-toggle autoHide="false">
              <ion-item routerLink="/my-side2" routerLinkActive="active" routerDirection="root" detail="false">
                <ion-icon slot="start" name="help"></ion-icon>
                <ion-label>
                  Terms of use
                </ion-label>
              </ion-item>
            </ion-menu-toggle>

          </ion-list>
        </ion-content>
      </ion-menu>
  <ion-router-outdlet id="content1"></ion-router-outlet>
</ion-app>

公式にも実装例が載っています。

https://ionicframework.com/docs/api/menu

任意のページからのサイドメニューの読み込み

以上でサイドメニューを設置できましたので、tab1ページから読み込んでみます。tab1.page.htmlはデフォルトではこのようになっていると思います。

<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Tab 1
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">
  <ion-header collapse="condense">
    <ion-toolbar>
      <ion-title size="large">Tab 1</ion-title>
    </ion-toolbar>
  </ion-header>

  <app-explore-container name="Tab 1 page"></app-explore-container>
</ion-content>

hdearの中で下記のタグで読み込めるようになりますので

      <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
      </ion-buttons>

tab1.page.htmlを丸ごとこのように変更します。

<ion-header>
  <ion-toolbar>
      <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
      </ion-buttons>
    <ion-title>
      File selection
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">
  <ion-header collapse="condense">
    <ion-toolbar>
      <ion-title size="large">Tab 1</ion-title>
    </ion-toolbar>
  </ion-header>

  <app-explore-container name="Tab 1 page"></app-explore-container>
</ion-content>

おまけ

サイドメニューから飛んだ先で戻るボタンを設置できます。

最初はこのようになっていると思いますが、

<ion-header>
  <ion-toolbar>
    <ion-title>mySide2</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

</ion-content>

下記のようにion-back-buttonを設置します。

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button defaultHref="/"></ion-back-button>
    </ion-buttons>
    <ion-title>
      Privacy policy
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

</ion-content>

そうするとこのように戻るボタンが設置できます。

Angular(Ionic)でグラフを描写する

グラフ描写のライブラリ

Ionicでグラフを描写するライブラリにはいくつかあるようですが、安定していてよく使われているchart.jsを使いことにしました。意外に簡単でびっくりしました。

インストール

プロジェクトのルートフォルダに移動して、Terminalで下記コマンドを実行します。

npm install chart.js --save

すると下記のようなメッセージが出てchat.jsがインストールされます。

+ chart.js@2.9.3
added 4 packages from 7 contributors, removed 1 package and audited 1527 packages in 12.531s

node_modulesのなかに格納されるので、これを使いたいページのtsファイルから呼び出すだけで使用できるようになります。

実装する

このような棒グラフを書いてみます。

参考サイト

https://enappd.com/blog/charts-in-ionic-4-apps-and-pwa-part-1/52/

HTMLファイルに要素を追加する

chart.jsはcanvas要素にグラフを描写するので、まずはグラフ要素をHTMLに記載します、

<ion-header>
</ion-header>

<ion-content>
=>  <canvas #myChart></canvas>
</ion-content>

描写する

あとはtsファイルからライブラリをimportしたあとにグラフを描写するだけです。HTMLの要素を取得するので、ViewChildも呼び出します。

import { Component, ViewChild } from '@angular/core';
import { Chart } from 'chart.js';

@Component({
  selector: 'app-admin',
  templateUrl: './admin.page.html',
  styleUrls: ['./admin.page.scss'],
})

export class AdminPage implements OnInit {

  @ViewChild('myChart') myChart;

  bars: any;
  colorArray: any;
  constructor() { }

  ionViewDidEnter() {
    this.createBarChart();
  }

  createBarChart() {
    this.bars = new Chart(this.myChart.nativeElement, {
      type: 'bar',
      data: {
        labels: ['Label1', 'Label2', 'Label3', 'Label4', 'Label5', 'Label6', 'Label7', 'Label8'],
        datasets: [{
          label: 'Viewers in millions',
          data: [25, 30, 50, 60, 92, 75, 100, 67],
          backgroundColor: 'rgb(50, 194, 129)', // array should have same number of elements as number of dataset
          borderColor: 'rgb(50, 194, 129)',// array should have same number of elements as number of dataset
          borderWidth: 1
        }]
      },
      options: {
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero: true
            }
          }]
        }
      }
    });
  }
}

pythonのリストをmap、filter、lambdaで操作する

操作対象のリストを作成

>>> lst = [i for i in range(10)]
>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

map関数で全体に対して操作

こういうリストがあったときに全体に対して操作するならこれ

>>> lst2 = list(map(lambda e:e*2,lst))
>>> lst2
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

python3では、map関数が返すものはmap objectなのでlistへ変換する必要がある。

filter関数で特定のものを抽出

>>> lst2 = list(filter(lambda e:e%2==0,lst))
>>> lst2
[0, 2, 4, 6, 8]

Agular(ionic)で多言語化対応を行う

環境

Ionic:

 Ionic CLI: 6.4.1 (/Users/myName/.nodebrew/node/v12.10.0/lib/node_modules/@ionic/cli)
   Ionic Framework  : @ionic/angular 5.1.1
   @angular-devkit/build-angular : 0.901.6
   @angular-devkit/schematics: 9.1.6
   @angular/cli   : 9.1.6
   @ionic/angular-toolkit : 2.2.0

Utility:
   cordova-res (update available: 0.14.0) : 0.9.0
   native-run (update available: 1.0.0)   : 0.2.9

System:
   NodeJS : v12.10.0 (/Users/masaya/.nodebrew/node/v12.10.0/bin/node)
   npm    : 6.14.2
   OS     : macOS Mojave



参考のサイト

公式ドキュメントはこちら

https://github.com/ngx-translate/core

パッケージのインストール

npm install @ngx-translate/core @ngx-translate/http-loader --save

package.json

  "dependencies": {
    "@ngx-translate/core": "^12.1.2",
    "@ngx-translate/http-loader": "^4.0.0",

実装

app.module.ts

app.module.tsにて、TranslateModuleをHttpClientModule, HttpClientと一緒にインポートします.

import {HttpClientModule, HttpClient} from '@angular/common/http';
import {TranslateModule} from '@ngx-translate/core';
・
  imports: [
    HttpClientModule,    
    TranslateModule.forRoot(),
  ],

使いたい場所のモジュール

使いたい場所のモジュールで

import {HttpClientModule, HttpClient} from '@angular/common/http';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';

export function createTranslateLoader(http: HttpClient) {
    return new TranslateHttpLoader(http, '../../assets/i18n/', '.json');
}
@NgModule({
    imports: [
      TranslateModule.forChild({
        loader: {
           provide: TranslateLoader,
           useFactory: (createTranslateLoader),
           deps: [HttpClient]
         }
      }),
    ],

使いたい場所のtsファイル

import {TranslateService} from '@ngx-translate/core';
 constructor(
    private translate: TranslateService,
  ) {
    this.translate.setDefaultLang('en');
    this.translate.use('en');
}

あとHTMLに

<p>{{ 'HELLO' | translate }}</p>

とかく

assetに情報を配置

最後に

/assets/i18n/

を作成して、jsonファイルをおけばいいです。

{
  "HELLO": "こんにちはEnglish"
}

複数の場合はこのように書いてください

{
  "Main": "メイン",
  "File selection": "ファイルの選択",
  "1. Choose a file": "1. ファイルの選択",
  "Pick a file from your storage": "ストレージから選択",
  "Or take a new picture": "新しく写真を撮る",
  "2. Crop your image": "2. 写真の切り抜き",
  "select the area you want to analyze from the photo": "解析したいエリアを選択してください",
  "No ads 3 times if you watch a short video": "広告が3回表示されなくなります!",
  "Preparing for the analysis. Since this app uses service that need to be payed(from not you but me), an ad will be shown to you.":"安全な方法でアップロードします。 このアプリは有料のAPIを使用しているため、広告が表示されます。",
  "Analyzing.":"分析しています。"
}

最後のブロックの後にカンマを入れるとエラーになりますので注意.

app.component.htmsも多言語化したい場合

app.module.tsを下記のようにします.

+import {HttpClientModule, HttpClient} from '@angular/common/http';
+import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
+import {TranslateHttpLoader} from '@ngx-translate/http-loader';

+export function createTranslateLoader(http: HttpClient) {
+    return new TranslateHttpLoader(http, '../assets/i18n/', '.json');
+}

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
+    TranslateModule.forRoot({
+      loader: {
+         provide: TranslateLoader,
+         useFactory: (createTranslateLoader),
+         deps: [HttpClient]
+       }
+    }),
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})
export class AppModule {}

app.component.ts

+import {TranslateService} from '@ngx-translate/core';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})
export class AppComponent {

  constructor(
+    private translate: TranslateService,
  ) {
+      this.translate.setDefaultLang('en');
+      this.translate.use('en');
  }
}

Ionic(Angular)のライフイベントについて

ライフイベント、ライフサイクルとは

ライフイベント、ライフサイクルとは、ページを読み込み、表示し、その後ユーザーが離脱する一連の流れの中で特定のタイミングで発火するDOMイベントのことです。Ionicでは、Ionic独自のライフイベントに加えて、Angularのライフイベントも利用することができます。

これにより、ページが読み込まれたらこれをする、ページに変化があったらこれをするといったことを実装できます。

Angularのライフイベントについて

 それまでまずはAngularのライフイベントからです。Ionicでは、Ionic独自のライフイベントに加えて、Angularのライフイベントも利用することができます。個人的にはAngularのイベントを使う頻度の方が高いです。

こちらの公式ドキュメントに細かく記載されておりますので、ここではよく使うライフイベントについて転載します。

https://angular.jp/guide/lifecycle-hooks

イベントフック(これを関数のように書いて呼び出します)概要
ngOnInit()ページやコンポートネントが最初に完全に読み込んだら実行されるものと理解しています。イメージではJavaScriptのonDOMcontentLOaded()です。その後、 ディレクティブ/コンポーネントを初期化します。ページ読み込みの際に1度だけ呼び出されます。
最初 の nOnChanges() の後に 一度 呼び出されます
ngOnChanges()Angular がデータバインドされた入力プロパティを(再)設定するときに応答します。 このメソッドは、現在および以前のプロパティ値の SimpleChanges オブジェクトを受け取ります。
ngOnInit() の前に呼び出され、データバインドされた入力プロパティが変更されるたびに呼び出されます。
ngOnDestroy()Angularがディレクティブ/コンポーネントを破棄する直前に、クリーンアップします。 メモリリークを回避するためにObservableの購読を解除し、イベントハンドラをデタッチしましょう。
Angularがディレクティブ/コンポーネントを破棄する 直前 に呼び出されます。

Angular場合、ライフサイクルはコンポーネントの生成や破棄がトリガーになります。そのため、最初の1回しかイベントを実行したくないときなどに利用します。

なお、constructorとngInitを同じように考えがちですが、前者はライフイベントではありませんので、コンポーネントが表示されるまで待ってくれません。そのため、constructorを実行したのになにも反映されないということがあります。constructorではページ操作を行うような動作は入れない方が良いです。

Ionicのライフイベント

 次にIonicのライフイベントです。

イベントフック(これを関数のように書いて呼び出します)概要
ionViewWillEnter()ページが表示されるアニメーションが始まるとき
ionViewDidEnter()ページが表示されるアニメーションが終了したとき
ionViewWilLeave()ページから離脱・遷移するアニメーションが始まるとき
ionViewDidLeave()離脱するアニメーションが終了したとき

Willのタイミングでデータの描画を行うのはよくないです。Will を使用する場合はデータの取得などの準備、Didを使用するのはデータを表示するなどのタイミングがよさそうです。

 Angularの場合、先に述べたようにコンポーネントがトリガーとなっているのに対して、lonicのライフライクルトリガーはユーザーにとっての表示です。なのでページ遷移して戻ってきたときにも発生するなどでUIの改善などの観点では非常に使いやすくなっています。

ライフイベントの実装方法

Ionicの場合、ライフサイクルイベントを関数のように追記するだけですが、Angularのライフサイクルイベントは先に型を定義する必要があります。

その他

IonicをAngularで使って、写真から文字情報を抽出して爆速でレポートや記事を作成するアプリを作成しています。無料なのでよかったらどうぞ。

iOS => https://apps.apple.com/app/id1497498494
Android => https://play.google.com/store/apps/details?id=com.rainbowsv2.ocr

Ionicの忘備録

Observableなオブジェクトの作成

import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
・
・
  constructor(
    private client:HttpClient
  ) { }  
・
・
devTestObservable(myStr):Observable<any> {
    return new Observable(observer => {
      setTimeout(() => {
        observer.next(myStr+'myObservable');
      }, 1000);
    })
  }

  devTestPromise() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('myPromise');
      }, 1000)
    })
  }

  devTestHttp():Observable<any> {
    return new Observable(observer => {
        this.client.get('/assets/data/test.json').subscribe(e =>{
          observer.next(e);
        })
    })
  }

Copy

  
import { DataService } from '../tabs/data.service';
import { HttpClient } from '@angular/common/http';
・
・
  constructor(
    private dataService:DataService,
    private client:HttpClient,
  ) {
      this.myStr = 'first ';
  }
・
・
async onButtonClick(){

    this.dataService.devTestHttp().subscribe(e =>{
      console.log(e,'Hi');
      this.myStr = e.authAdmin.linkLoginButton+'Hi';
    })

    this.dataService.devTestObservable().subscribe(e =>{
      console.log(e);
    })

    this.dataService.devTestPromise().then(e =>{
      console.log(e);
    })

  }

Copy

input

<ion-item lines=’full’><ion-label position=’floating’>らべる</ion-label><ion-input type=’text’></ion-input></ion-item>

inputには、最初にplaceholderが表示されていて、フォーカスをあてるとplaceholderのラベルが左上に移動するものが一番いいです。

こんな感じになります。

フォーカス前

フォーカス後

ボタン

横いっぱいに広がったよく見るボタンが表示されます。クリック時の関数は(click)=で指定します。

<div><ion-button expand=’block’ (click)=”someFunc()”>Button</ion-button></div>

新しい部品をつくる

ionic g

とだけ入力すれば、下記の選択肢を表示してくれます。

まだオンプレミスで消耗してるの?Firebaseについて

サーバを立てるのは常識だった

 以前はなにかサービスを作ろうと思うと、サーバを立てて運用するというのが常識でした。物理的なサーバを購入して自社や自宅に置くことはもちろんですが、そうでなくてもVPSで借りて運用するなどは常識だったと思います。WebならPHPでのバックエンドになりますし、アプリの開発ならRestAPIなどを設計したでしょうか。いずれにせよ、サーバを借りてプログラムを書くという点は常識でした。

サーバの運用は大変

 しかしサーバの運用は大変なものです。プログラムを設置し、アクセスを適切に受けるようにして、セキュリティも考慮しなければなりません。OSの設定も大変ですし、物理的なサーバなら電源の冗長化や放熱なども考慮する必要があります。わたしも昨年、会社でDellのWindows Serverを購入しましたが、初期投資は150万円かかりましたし、場所を確保したり専用クーラを設置したり導入までに3ヶ月程度はかかりました。

クラウドがあるじゃないか

 こうした負担を軽減する方法はないのか?と考えた時にクラウドがあります。

クラウドはGoogleやAmazon、Microsoftなどがネット上に構築したサービス群で、OSをVPNのように提供する低レベルなものから(IaaS)、サービスだけを提供するSaaSレベルのものもあります。そして必要なものを選んで利用するほうが、自前でサーバを運用するより圧倒的に楽です。

従来と比べて大きく違うのは、まず初期コストはゼロというです。そして、サーバを運用し続ける負担がほぼなくなります。インフラの部分の担当を任せられるのですから非常にらくになります。これにより爆発的な導入がなさされておりますが、「セキュリティ」を理由に導入していないところも多くあると思いますが、官公庁ではAWSを使ったり、NetFlixのような非常に大規模サイトでも使用されています。

その他、個人的に感じるクラウドの強みは、開発者が納得いくまで何度でもやり直せる点です。先ほど述べたように、わたしは昨年DellのWindows Serverを購入しましたが、「とりあえず動くようにプログラム設置できたら、あとは怖いから放置」ということになってしまっています。実際、一念発起しても杞憂に終わらなかったですし。。一方、クラウドはサービスなので何度でも自分が納得するまで設定をして消去ということを繰り返すことができます。テスト環境を作って、なっとくするまで設定する、そしてうまくいったものだけで本番環境で再現できるとなれば、取り合えず動くようになったら放置というオンプレミス環境と比べて大きくプログラムへの理解が深まります。

Firebaseとは

サーバレスを実現するクラウドサービスはいろいろありますが、特に利用されるのがFirebaseです。現在はGoogle(Alphabet)の傘下ですが、スタートアップだったものをGoogleが買収したものです。

Firebaseの機能

スマホアプリ開発におけるバックエンドを担うことがおおいようですが、JavaScript,JAVA,Swift,Objective-C、Swift、C++、Unity、Python、PHP、Goなどほとんどの環境からアクセスできます。

機能はこちらです

ユーザー認証非常にいやらしい認証周りを簡素化するFirebaseの代表的なサービスです。IDとパスワードで実現するものに加えて、GoogleやTwitter、 Facebookなどのアカウントを利用したユーザー認証や匿名認証も可能です。
データベース「キー=バリュー型」の非SQLデータベース(Json形式)です。SQLの使えるRDBは連携しているGCPで利用できるのでFIrebaseにはNoSQLが搭載されています。ソケット通信で接続しておいて、変更があったらフロント側のデータを自動で更新してくれるので非常に便利です
ストレージファイルの保管機能。普通に画像などをストレージできます
ホスティングWebサイトをデプロイし、公開します
クラウドファンクションネットワーク経由で特定の処理を呼び出し、実行します。Pythonで書くこともできます。このURLを叩いたらPythonプログラムを実行して解析した結果を返すといったことができます
機械学習キット言語翻訳、写真からのテキスト認識、顔認証などです
Google AnalyticsGoogle Analyticsによるアクセス解析です
メッセージングスマホアプリへのプッシュ通信を実現します。Niftyなどでもできるようですが、FIrebaseがメジャーかと。。

いくらかかるのか

実際はGCPと連携して使う場合もあり一概にはいえないですが、使い始めてすぐお金がかかるようにはなっていません。2種類の料金プランが用意されていて、まずは一ひとつめのSparkプラン(無料枠)から始めるようになっているためです。Sparkプランだけでもデータの保存に1GB/月、読み込みに10GB/月が設定され、認証は1 万/月可能なのでかなりでかいです。料枠を超えると利用量に応じた料金が自動的にかかる仕組みです。

公式によると下記の料金体系となっています。

プロダクト  無料Spark プランGenerous limits to get started従量制Blaze プラン大規模なアプリの料金を計算checkSpark プランの無料使用量を含む*
A/B テスト無料
Analytics無料
App Distribution無料
App Indexing無料
認証電話認証 – 米国、カナダ、インド help電話認証 – 他のすべての国 help他の認証サービス1 万/月1 万/月check$0.01/認証$0.06/認証check
Cloud Firestore保存データ下りネットワークドキュメントの書き込みドキュメントの読み取りドキュメントの削除合計 1 GiB10 GiB/月2 万/日5 万/日2 万/日$0.18/GiBGoogle Cloud pricing$0.18/10 万$0.06/10 万$0.02/10 万
Cloud Functionshelp呼び出しGB 秒CPU 秒アウトバウンド ネットワーキング12.5 万/月4 万/月4 万/月Google サービス専用$0.40/百万$0.0025/千$0.01/千$0.12/GB
Cloud Messaging(FCM)無料
Crashlytics無料
Dynamic Links無料
HostingGB 保存済みGB 転送済みカスタム ドメインと SSLプロジェクトごとに複数のサイト1 GB10 GB/月checkcheck$0.026/GB$0.15/GBcheckcheck
アプリ内メッセージング無料
ML Kithelpデバイス用 APIカスタムモデルのホスティング / サービス提供AutoML Vision Edge データセットAutoML Vision Edge トレーニング

Cloud Vision API
checkcheck画像 1,000 件/プロジェクト3 時間/プロジェクト

close
checkcheckGoogle Cloud pricing15 時間/請求先アカウント、
$4.95/時間$1.50/1,000
Cloud Vision の料金を参照)
パフォーマンス監視無料
Predictions無料
Realtime Database同時接続 helpGB 保存済みGB ダウンロード済みプロジェクトごとに複数のデータベース1001 GB10 GB/月close20 万/データベース$5/GB$1/GBcheck
Remote Config無料
ストレージhelpGB 保存済みGB ダウンロード済みオペレーションをアップロードダウンロード オペレーションプロジェクトごとに複数のバケット5 GB1 GB/日2 万/日5 万/日close$0.026/GB$0.12/GB$0.05/1 万$0.004/1 万check
Test Labhelp仮想デバイスでのテスト物理デバイスでのテスト10 件/日5 件/日$1/デバイス/時間$5/デバイス/時間
Google Cloud PlatformBigQuery およびその他の IaaS を使用 helpclosecheck
プランを選択Looking for the Flame plan?無料Spark プランすぐに開始可能従量制Blaze プランプランを選択

その他

写真から文字情報を抽出して爆速でレポートや記事を作成するアプリを作成しています。無料なのでよかったらどうぞ。フロントエンドはAngularで開発し、バックエンドはGCPとFirebaseを使っています。

iOS => https://apps.apple.com/app/id1497498494
Android =>  https://play.google.com/store/apps/details?id=com.rainbowsv2.ocr

PythonとAngularの組み合わせが最強な理由

クロスプラットフォームは生産性が高い

 なにかをサービスインしようとしたとき、Androidだけ、iOSだけ、あるいはWebだけというのは片手落ちです。だからといってAndroid用にKotlinで開発し、iOS用にSwiftで開発し、そしてWeb用にも別個に開発など現実的ではありません。

 すでに大成功しているソフトならもちろんありですが、現実はうまくいくか保証のないまま開発し、なるべく多くのユーザーに使ってもらいながら成功につなげていきたいと考えると思います。だからこそ、クロスプラットフォームであることは特に個人や小規模の開発チームにとって必須のツールとなると考えています。

ここでは、フロントエンドとしてAngular,バックエンドとしてPythonという組み合わせがメリットの大きな組み合わせであることを解説します。

どこのプラットフォームを抑えるか

すぐに思いつくプラットフォームとしては、デスクトップ、スマホアプリ、Webです。

  • デスクトップアプリ
    Linuxは置いておいてもMacとWindowsがあります
  • スマホアプリ
    AndroidとiOSがあります
  • Web
    これはユーザーに非常に簡単にアクセスできるプラットフォームとして外すことはできないです

ユーザーは各プラットフォームに分散していますが、個人的にはWebとスマホアプリを抑えればほとんどカバーできると考えており、デスクトップアプリの優先度は低いと思っています。したがって、クロスプラットフォームの環境はUnity,Xamarin,Cordova,Ionic,React,Capacitorなどがあると思いますが、Ionic,React,CordovaなどのWeb系の技術が選択肢として残ります。

さらにそのなかでどのフレームワークが強いかをこちらの記事で考えたのですが、私の意見ではAngularが断然オススメです。

https://np-sys.com/general/%e5%80%8b%e4%ba%ba%e3%83%bb%e5%b0%91%e4%ba%ba%e6%95%b0%e3%81%ae%e3%82%b7%e3%82%b9%e3%83%86%e3%83%a0%e9%96%8b%e7%99%ba%e3%81%ab%e3%81%afangular%e3%81%8c%e3%82%aa%e3%82%b9%e3%82%b9%e3%83%a1/

バックエンドはどうするか

Angularでフロントエンドを書くとするとバックエンドはどうすればいいでしょうか。TypeScriptが使えるのでnode.jsで書くのはもちろんいいと思います。PHPエンジニアもいると思います。

 ただ、わたしはバックエンドはPythonが好きです。もともとPythonがもっとも馴染みのある言語ということがありますが、バックエンドというのはデータ処理が少なからずあると思うのです。例えばAIを搭載したアプリケーションを開発する場合を考えた時、AIはほぼPython一択です。そうでなくても多くのデータ処理を実行する可能性は多いにあるため、node.jsでもなくPHPでもなく、バックエンドはPythonが汎用性が高いと考えます。Pythonで書いておけばカバー範囲が広いと思っており、バックエンドはPythonで作成したAPIで担当させておいて、AngularからそのAPIを叩いてデータ処理を行うというイメージです。

組み合わせるとどうなるか

 AngularをIonicで使用すると、見た目は完全にNativeになります。Nativeに比べると挙動が遅いということですが(https://developer.medley.jp/entry/2017/11/24/120000)、現在のスマートフォンの性能なら描写の多いゲームなどを除いてまったく問題ならないと思います。したがって、Ionicで開発しておけば、ひとつのプロジェクトをつくるだけでAndroid,Web,iOSのプラットフォームに高いクオリティでビルドできます。そしてバックエンドはPythonで受ける。これによって高い生産性と拡張性を備えたシステムが開発ができると考えているため、これが個人の開発や小規模でも開発を実施する場合私の考える最強の組みわせです。

榊原昌彦さんのコメント

とても共感したので、こちらの著者である榊原昌彦さんの冒頭の挨拶を引用させていただきます。

大きく変わったWebの価値Web技術で作ることができるプロダクトの選択肢は大きく増えました。Web Native開発フレームワークの「Ionic Framework」を使えば、Mobile Native,と同じようなUIとUXをユーザに提供することができます。クロスプラットフォームライブラリ「Capacitor」を利用すれば、Webアプリを「App Store」(iPhone/iPad) や「Google Play」(Android)で配信することができます。Google Chromeをはじめとしたインターネットブラウザも大きく進化しました。モバイルアプリ同等のUX(ユーザ体験)を提供することを目指して、今までモバイルアプリでしか実現できなかったプッシュ通知やオフラインでの表示、高精度GPSといった機能をWebで提供できます。また、「Electron」というWebアプリをデスクトップアプリにすることができるフレームワークが利用されるシーンも増えています。今では、WebアプリのプラットフォームはWebだけではなくなり、1つのプロダクトをiOS、Android、デスクトップへと、ハイブリッドに展開できるようになっています。Webとモバイルの境目がなくなりつつある多くのWebサイト、Webアプリではモバイルデバイスからのアクセス数が増え続けており、モバイルファースト(モバイルデバイスを利用するユーザを優先した設計)が当たり前になりつつあります。ユーザが、「ホーム画面に追加」という機能を使えば、Webをモバイルアプリのように利用できます。Webアプリとモバイルアプリの違いは、アプリストアからインストールするか、ブラウザからアクセスするかの違いになりつつあります。その中で、ハイブリッドに展開する大きなメリットは「そこにユーザがいるから」です。皆さんが作ろうとしているアプリのユーザは、Webブラウザをよく使いますか? Androidユーザが多いですか? もしかすると、App Storeでアプリを探すような人かもしれません。Webとモバイルの境目がなくなりつつある今だからこそ、プラットフォームに依存しない形であなたのアイデアを実現できることは大きな武器になります。

個人的にはこれにPythonを加えると最強だと考えています。

最後に

写真から文字情報を抽出して爆速でレポートや記事を作成するアプリを作成しています。無料なのでよかったらどうぞ。フロントエンドはIonicでCapacitorを使って開発し、バックエンドはGCPのApp EngineをPythonで書いてます。

iOS => https://apps.apple.com/app/id1497498494
Android => https://play.google.com/store/apps/details?id=com.rainbowsv2.ocr

Angularにおけるモジュール解説

モジュールとは

Anularは、コードをモジュールという単位で機能ごとに分割することで管理します。電気自動車が部品を組み立てることで比較的簡単に組み立てられるように、機能ごとにモジュールへ分割することでプログラムを作成しやすくなります。代表的なものとして、ルーティングや HTTP 通信などの機能を持つものなどがあります。

CommonModule

CommonModuleはNgIf や NgFor などの基本的なディレクティブやパイプを提供します。両者ともAngularを代表する機能ですが、Ngifは変数の条件によって(例えばログインしているかしていないかで)表示を変えるときに使用しますし、NgForはリスト構造になっているものに対してイテレートすることで劇的にソースコードを書く手間を低減できます。Angularを代表する機能であるモジュールのため直接読み込む必要はなく、BrowserModule やWorkerAppModule などの各プラットフォームごとのモジュールがエクスポートしているので、これらのモジュールを読み込んでいれば同時に利用可能になります。

Forms Module

Forms Moduleは、Template Driven なフォームを実装するのに必要となるディレクティブやプロバイダを提供します。Template Driven はフォームにユーザーが入力した情報によって変数側のデータを書き換える方法で、これによりJavaScriptからクラスやIDを指定してgetElementbyID()などの手間を省くことができます。Forms Module は、@angular/forms からインポートすることで利用できます。

src/app/app.module.ts

import { NgModule }      from '@angular/core';import { BrowserModule } from '@angular/platform-browser';import { FormsModule }   from '@angular/forms';import { AppComponent }  from './app.component'; @NgModule({imports: [BrowserModule,FormsModule],declarations: [AppComponent,],providers: [],bootstrap: [ AppComponent ]})export class AppModule { }

Reactive FormsModule

ReactiveForms Module は、アプリケーションに Reactive Form を実装するために必要なディレクティブやプロバイダを提供します。Forms Moduleがユーザー側の入力でバックエンド側の変数を書き換える方法なのに対して、このモジュールはバックエンド側からフロントエンドを書き換える方法です。ReactiveForms Module は Forms Module と同様に、@angular/forms からインポートして利用します。

HttpClientModule

HttpClientModule は、HTTP リクエストや、レスポンスの処理を実装するのに必要なプロバイダを提供します。Pythonなどとは異なり非同期通信だるJavaScript(そしてSupersetであるTypeScript)では、Ajax通信をよく使いますが、Ajax通信をAngularで実装する際はこのモジュールを使用します。AjaxHttpClientModule は @angular/common/http からインポートすることで利用可能になります。

JsonpModule

JsonpModule は、JSONP を用いた HTTP 通信を実装するのに必要なプロバイダを提供します。JsonpModule は HttpClientModule と同様、@angular/http からインポートすることで、利用可能になります。個人的にはあまり使用したことはありません。

Router Module

AngularはSPAですので、実態は一枚のHTMLのDOMを書き換えてページ遷移を実現します。その際のURL変更に関する機能を担当するモジュールです。RouterModule は @angular/router からインポートすることで利用します。

BrowserModule 

BrowserModule は、DOM イベント(たとえばheaderの読み込みが完了したかなど(https://phpjavascriptroom.com/?t=js&p=event))やキーボードイベント・タッチイベントなど、主にブラウザアプリケーションの作成に必要な機能を提供します。これもWebからきている人には理解しやすい概念だと思います。なお、BrowserModule のなかでCommonModule もエクスポートしているため、BrowserModule をインポートするだけでCommonModule も読み込まれます。@angular/platform-browser からインポートして利用しますが、個人的には何も考えずにインポートするモジュールです。

ServerModule

ServerModule は、主にサーバーサイドレンダリングを行うアプリケーションを作成するために必要な機能を提供します。公式を見ると解説が省略されすぎているのですが。。

https://angular.io/api/platform-server/ServerModule

前述の BrowserModule もエクスポートしているので、BrowserModule で使える機能も利用できます。@angular/platform-server からインポートします。サーバ側はPythonで書くことが多いので、あまり個人的に使用したことはありません。

WorkerAppModule

これも個人的にはほとんど使ったことがないモジュールで、公式によると、Angular10から廃止されることが決まっておりますので使用しないほうがいいでしょう。

https://angular.jp/api/platform-webworker/WorkerAppModule

まとめと結論

Anularは、モジュールという単位で特定の機能を担うコードを分割し、使用する場合はImportしてすぐに使用できるようにしています。個人的には、

  • 存在をしっていればいいもの
    BrowserModule
  • 使う中でわかってくるもの
    Forms Module、Reactive FormsModule
  • 勉強して使えるようにならないといけないもの
    HttpClientModule

というイメージです。

写真から文字情報を抽出して爆速でレポートや記事を作成するアプリを作成しています。無料なのでよかったらどうぞ。

iOS => https://apps.apple.com/app/id1497498494
Android =>  https://play.google.com/store/apps/details?id=com.rainbowsv2.ocr