1. はじめに
目標
このコードラボでは、 Firebase Extensionsを利用してオンライン マーケットプレイス アプリに機能を追加します。このコードラボを通じて、拡張機能がアプリの開発および管理タスクに費やす時間を短縮するのにどのように役立つかを理解できます。
何を構築するか
このコードラボでは、オンライン マーケットプレイスの Web アプリに次の機能を追加します。
- 画像の読み込みを高速化してユーザー維持率を向上
- データベース内のエントリを制限してパフォーマンスを向上させ、請求額を削減します
- ユーザーデータの保護を強化するために、古いユーザーデータの自動削除を実装します。
学べること
- 一般的なユースケースの拡張機能を見つける方法
- プロジェクトに拡張機能をインストールして構成する方法
- プロジェクト内の拡張機能を維持 (監視、更新、アンインストール) する方法
このコードラボは Firebase Extensions に焦点を当てています。このコードラボで説明されている他の Firebase 製品の詳細については、 Firebase ドキュメントおよび他のコードラボを参照してください。
必要なもの
- 最新の Web ブラウザがインストールされているコンピュータ (Chrome を推奨)
- Googleアカウント
2. Firebase プロジェクトを作成して設定する
Firebaseプロジェクトを作成する
- Firebase コンソールで、 [プロジェクトの追加]をクリックし、Firebase プロジェクトにFriendlyMarketという名前を付けます。
- クリックしてプロジェクト作成オプションを選択します。 Firebase の利用規約に同意します。このアプリでは Analytics を使用しないため、Google Analytics の設定はスキップします。
- プロジェクトがプロビジョニングされるのを待って、 「続行」をクリックします。
構築するアプリケーションでは、ウェブアプリで利用可能ないくつかの Firebase 製品を使用します。
- ユーザーを簡単に識別するためのFirebase Authentication
- Firebase Realtime Databaseは構造化データをクラウドに保存し、データが更新されたときに即座に通知を受け取ります
- 画像をクラウドに保存するCloud Storage for Firebase
次に、Firebase コンソールを使用して、これらの Firebase 製品を有効にして構成します。
電子メールログインを有効にする
認証はこのコードラボの焦点ではありませんが、アプリを使用するすべてのユーザーを一意に識別するために、アプリに何らかの形式の認証を設けることが重要です。電子メールによるログインを使用します。
- Firebase コンソールの左側のパネルで[開発]をクリックします。
- [認証]をクリックし、 [サインイン方法]タブをクリックします (または、ここをクリックして[サインイン方法]タブに直接移動します)。
- [サインイン プロバイダー]リストで[電子メール/パスワード]をクリックし、 [有効]スイッチをオンの位置に設定して、 [保存]をクリックします。
リアルタイムデータベースを有効にする
このアプリは Firebase Realtime Database を使用して販売用のアイテムを保存します。
- Firebase コンソールの左側のパネルにある[開発]セクションで、 [データベース]をクリックします。
- ページを下にスクロールしてCloud Firestore ペインを通過し、 [Realtime Database]ペインで[データベースの作成]をクリックします。
- [ロック モードで開始]を選択し、 [有効にする]をクリックします。
セキュリティルールを設定する
次に、このアプリに必要なセキュリティ ルールを設定します。これらは、アプリのセキュリティを確保するのに役立つ基本的なルールの例です。これらのルールでは、誰でも販売アイテムを表示できますが、サインインしているユーザーのみがその他の読み取りと書き込みを実行できます。これらのルールの詳細については心配する必要はありません。これらをコピーして貼り付けるだけで、アプリを起動して実行できます。
- Realtime Database ダッシュボードの上部で、 「ルール」タブをクリックします。
- 次のルール セットをコピーして、 [ルール]タブのルール フィールドに貼り付けます。
{
"rules": {
".read": false,
".write": false,
"drafts": {
".indexOn": "seller",
".read": "auth.uid !== null",
".write": "auth.uid !== null"
},
"sellers": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
},
"forsale": {
".read": true,
".write": "auth.uid !== null"
}
}
}
- 「公開」をクリックします。
クラウドストレージを有効にする
このアプリは、Cloud Storage for Firebase を使用して販売アイテムの画像を保存します。
- Firebase コンソールの左側のパネルにある[開発]セクションで、 [ストレージ] をクリックします。
- 「開始する」をクリックします。
- デフォルトのストレージ バケットを作成するためのデフォルトを受け入れます (「次へ」をクリックし、デフォルトの場所をそのままにして「完了」をクリックします)。
次に、このアプリに必要なセキュリティ ルールを設定します。これらのルールでは、認証されたユーザーのみが新しい画像を投稿できますが、リストされたアイテムの画像は誰でも閲覧できます。
- ストレージダッシュボードの上部で、 [ルール]タブをクリックします。
- 次のルール セットをコピーして、 [ルール]タブのルール フィールドに貼り付けます。
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
match /friendlymarket/{ImageId} {
allow read;
allow write: if request.auth != null;
}
}
}
- 「公開」をクリックします。
3. サンプルアプリを実行する
StackBlitz プロジェクトをフォークする
このコードラボでは、いくつかの Firebase ワークフローが統合されたオンライン エディタであるStackBlitzを使用してアプリを構築し、デプロイします。 Stackblitz にはソフトウェアのインストールや特別な StackBlitz アカウントは必要ありません。
StackBlitz を使用すると、他のユーザーとプロジェクトを共有できます。あなたの StackBlitz プロジェクト URL を知っている他の人は、あなたのコードを見てプロジェクトをフォークすることができますが、StackBlitz プロジェクトを編集することはできません。
- 開始コードについては、次の URL にアクセスしてください: https://stackblitz.com/edit/friendmarket-codelab 。
- StackBlitz ページの上部にある[フォーク]をクリックします。
これで、独自の StackBlitz プロジェクトとして開始コードのコピーが作成されました。サインインしていないため、「アカウント」は@anonymous
と呼ばれますが、それは問題ありません。プロジェクトには一意の名前と一意の URL が付いています。すべてのファイルと変更は、この StackBlitz プロジェクトに保存されます。
Firebase Web アプリをプロジェクトに追加する
- StackBlitz で、
src/firebase-config.js
ファイルを表示します。ここに Firebase 構成オブジェクトを追加します。 - Firebase コンソールに戻り、左上の [プロジェクトの概要] をクリックしてプロジェクトの概要ページに移動します。
- プロジェクトの概要ページの中央にある Web アイコンをクリックします。 新しい Firebase ウェブアプリを作成します。
- アプリをFriendlyMarket Codelabというニックネームで登録します。
- このコードラボでは、 [このアプリの Firebase Hosting もセットアップする] の横のボックスをオンにしないでください。代わりに StackBlitz プレビュー ペインを使用します。
- [アプリの登録]をクリックします。
- アプリの Firebase 構成オブジェクトをクリップボードにコピーします。
<script>
タグをコピーしないでください。注: 後で構成を見つける必要がある場合は、ここの手順に従ってください。
- 「コンソールに進む」をクリックします。
プロジェクトの構成をアプリに追加します。
- StackBlitz に戻り、
src/firebase-config.js
ファイルに移動します。 - 構成スニペットをファイルに貼り付けます。これを実行すると、次のようになります (ただし、構成オブジェクトには独自のプロジェクトの値が含まれています)。
このアプリの出発点は何ですか?
StackBlitz 画面の右側にあるインタラクティブなプレビューを見てください。
このコードラボでは、基本的なマーケットプレイス アプリのコードから始めます。どのユーザーも販売中のアイテムのリストを表示し、リンクをクリックしてアイテムの詳細ページを表示できます。ユーザーがサインインしている場合は、販売者の連絡先情報が表示され、価格を交渉して商品を購入できます。
アプリを試してみましょう:
- ホーム画面上部のボタンからサインインします。偽の電子メール アドレス、名前、パスワードを使用することができます。
- 右下隅にある「何かを販売」ボタンをクリックしてリストを作成します。
- [タイトル]に
Xylophone
と入力します。 - [希望価格]に
50
と入力します。 - [アイテムの説明]に次のように入力します:
This high quality xylophone can be used to play music.
- この木琴の画像をコンピュータにダウンロードし、 [商品の画像]ボタンを使用してアップロードします。
- すべてのフィールドに入力して画像をアップロードしたら、 [投稿]をクリックします。
- 新しいリストを見つけてください。アイテムをクリックして詳細画面を表示し、販売者の連絡先情報パネルを展開します。
- Firebase コンソールに戻ります。データベースダッシュボードの
forsale
ノードの下に投稿したアイテムのエントリが表示されます。ストレージダッシュボードには、friendlymarket
パスにアップロードした画像も表示されます。
4. 拡張機能を見つけてインストールする
問題
アプリのユーザー調査を行った結果、ほとんどのユーザーがデスクトップではなくスマートフォンからサイトにアクセスしていることがわかりました。ただし、統計は、モバイル ユーザーがわずか数秒でサイトを離れる (「離脱」する) 傾向があることも示しています。
興味があったので、モバイル接続速度でサイトをテストします。 (その方法については、こちらをご覧ください。) 画像の読み込みに非常に時間がかかり、ブラウザにまったくキャッシュされていないことがわかります。ページビューごとに長い読み込み時間が発生します。
ソリューション
画像を最適化する方法を読んだ後、画像の読み込みパフォーマンスを向上させるために 2 つの手順を実行することにしました。
- 画像を圧縮します。携帯電話でも、このアプリのニーズに必要な解像度よりもはるかに高い解像度で画像が撮影されます。ファイル サイズを小さくすると、アプリの解像度が大幅に低下することなく、読み込み時間が短縮されます。
- キャッシング。デフォルトでは、Cloud Storage オブジェクトにはブラウザに画像をキャッシュしないよう指示するヘッダーがあります。つまり、ユーザーのブラウザは同じ画像を何度も再ダウンロードすることになります。幸いなことに、これらのヘッダーを変更してキャッシュを許可することができます。クライアント側の Cloud Storage SDKとFirebase Admin SDKの両方で、これらのヘッダーを設定できます。
画像を圧縮するには、アップロードの品質を制限するか、画像のサイズを変更するサーバー側のプロセスを使用する必要があります。トレードオフを考えてみましょう。
- クライアント側。クライアント側プロセスの場合は、アップロードされる画像のファイル サイズを制限するだけで済みます。これは、新しいサーバー ロジックを作成したり保守したりする必要がないことを意味します。ただし、これは販売者が自分の画像のサイズを変更する方法を理解する必要があることも意味しており、これは新しい商品を作成する際の苦痛で非直感的な障壁となっています。
- サーバ側。 Cloud Functions for Firebase を使用している場合は、アップロード時に画像のサイズを自動的に変更する関数をトリガーできます。これは、販売者が好きなサイズの画像をアップロードでき (追加の作業は必要ありません)、バックエンド機能で画像のサイズをシームレスに変更できることを意味します。この機能のサンプルも用意されています。
サーバーサイドが最適な方法のようです。ただし、このアイデアでも、サンプルのクローンを作成し、セットアップ手順に従って、Firebase CLI を使用して関数をデプロイする必要があります。画像のサイズ変更は、よくある使用例のように思えます。もっと簡単な解決策はないでしょうか?
より簡単な解決策
あなたは幸運です。もっと簡単な解決策があります: Firebase Extensions です。 Firebase Web サイトで利用可能な拡張機能のカタログを確認してみましょう。
あれ見てよ! 「Resize Images」という拡張機能があります。それは期待できそうです。
この拡張機能をアプリで使用してみましょう。
拡張機能をインストールする
- この拡張機能に関する詳細を表示するには、「詳細を表示」をクリックします。 [構成できる内容]で、拡張機能を使用すると、サイズを変更する寸法を設定でき、キャッシュ ヘッダーを設定することもできます。完璧!
- 拡張機能の詳細ページで「コンソールにインストール」ボタンをクリックします。すべてのプロジェクトがリストされた Firebase コンソール ページが表示されます。
- このコードラボ用に作成したFriendlyMarketプロジェクトを選択します。
- 「拡張機能の構成」ステップに到達するまで、画面上の指示に従います。この手順には、拡張機能の基本的な概要と、拡張機能が作成するリソースと必要なロールにアクセスするためのリソースが表示されます。
- サイズ変更された画像の**
Cache-Control
** ヘッダー フィールドに、次のように入力します。
public, max-age=31536000
- 他のパラメータはデフォルト値のままにしておきます。
- 「拡張機能のインストール」をクリックします。
インストールが完了するのを待っている間...
Firebase コマンドライン インターフェイスを使用したインストール
コマンドライン ツールに慣れている場合は、Firebase CLI を使用して拡張機能をインストールおよび管理することもできます。最新バージョンの CLI で利用できるfirebase ext
コマンドを使用するだけです。詳細については、こちらをご覧ください。
(オプション) Cache-Control ヘッダーの詳細については、こちらをご覧ください。
Cache-Control ヘッダー値public, max-age=31536000
画像が最大 1 年間キャッシュされることを意味します。 Cache-Control ヘッダーの詳細については、このドキュメントを参照してください。
クライアントコードを更新する
インストールした拡張機能は、サイズ変更された画像を元の画像と同じバケットに書き込みます。サイズ変更された画像には、設定された寸法がファイル名に追加されます。したがって、元のファイル パスがfriendlymarket/user1234-car.png
のようになった場合、サイズ変更された画像のファイル パスはfriendlymarket/user1234-car_200x200.png
のようになります。
フルサイズの画像ではなく、サイズ変更された画像を取得するようにアプリを更新してみましょう。
- StackBlitz で、
src/firebase-refs.js
ファイルを開きます。 - 既存の
getImageRef
関数を次のコードに置き換えて、サイズ変更された画像の参照を作成します。
export function getImageRef(storage, imagePath) {
const xDimension = 200;
const yDimension = 200;
// find the '.' in 'file.jpg', 'file.png', etc
const fileExtensionIndex = imagePath.lastIndexOf('.');
const pathNameWithoutExtension = imagePath.substring(0, fileExtensionIndex);
const dimensions = `${xDimension}x${yDimension}`;
const fileExtension = imagePath.substring(fileExtensionIndex);
return {
resized: storage().ref(
`${pathNameWithoutExtension}_${dimensions}${fileExtension}`
),
original: storage().ref(imagePath)
};
}
試してみてください
この拡張機能は新しい画像のアップロードを監視するため、既存の画像のサイズは変更されません。
新しい投稿を作成して、拡張機能の動作を確認します。
- アプリの上部バーにある[Friendly Market]をクリックして、ホーム画面に移動します。
- アプリの右下隅にある「何かを販売」ボタンをクリックしてリストを作成します。
- [タイトル]に
Coffee
と入力します - [希望価格]に
1
を入力します。 - [商品説明]に、次のように入力します:
Selling one cafe latte. It has foam art in the shape of a bear
。 - このコーヒーカップの画像をコンピュータにダウンロードし、 [商品の画像]ボタンを使用してアップロードします。
- すべてのフィールドに入力して画像をアップロードしたら、 [投稿]をクリックします。木琴の下にコーヒーのリストが表示されます。
- Firebase コンソールのFunctionsダッシュボードで、 [Logs]タブをクリックします。関数が実行されたことを示す関数からのログが表示されるはずです。
- ストレージダッシュボードに移動して、
friendlymarket
パスにある元のコーヒー画像とサイズ変更されたバージョンの両方を確認します。 - StackBlitz のプレビュー ペインで、アプリのホーム画面を数回リロードします。コーヒーの画像の読み込みが木琴の画像よりも大幅に速いことに気づくはずです。
画像はサイズが小さいため、最初のページの読み込みでは高速に読み込まれます。その後のページの更新では、ネットワーク要求をトリガーする代わりにブラウザーのキャッシュから読み込まれます。
5. 拡張機能を再構成する
問題
アプリは販売者のリストの下書きバージョンを自動保存します。ユーザーはこの機能を気に入っていますが、統計情報は少し心配です。レポートによると、実際に投稿されるのは下書きの約 10% だけで、残りの 90% はデータベース内のスペースを占有しているだけです。
ソリューション
現実的な計算を行った結果、一度に保存する必要があるのは下書き 5 つだけであることがわかりました。
Firebase Extensions のカタログを覚えていますか?もしかしたら、この状況に対する解決策がすでに構築されているかもしれません。保存されたドラフトの数を自動的に 5 つ以下に保つために、Limit Child Nodes拡張機能をインストールしましょう。新しいドラフトが追加されるたびに、拡張機能は最も古いドラフトを削除します。
- 拡張機能の詳細ページで「インストール」ボタンをクリックします。
- マーケットプレイス ウェブ アプリに使用している Firebase プロジェクトを選択します。
- 「拡張機能の構成」ステップに到達するまで、画面上の指示に従います。
- [Realtime Database path]に、
drafts
と入力します。これは、下書きが保存されるデータベース内のパスです。 - [保持するノードの最大数]に
5
を入力します。これは、アイテムのリストごとに 5 つの下書きが保存され、別の下書きが追加されると、最も古い下書きが自動的に削除されることを意味します。 - 「拡張機能のインストール」をクリックします。
インストールが完了するのを待っている間...
監視拡張機能
拡張機能をインストールすると、プロセスによっていくつかの関数が作成されます。これらの関数が実行される頻度を確認したり、ログやエラー率を表示したりすることができます。拡張機能を監視する方法の詳細については、 「インストールされた拡張機能を管理する」を参照してください。ドキュメントの指示に従って、前の手順で Resize Images 拡張機能によって作成された関数を表示します。
拡張機能のアンインストール
プロジェクトから拡張機能を削除するには、拡張機能が作成する個々の関数を削除したくなるかもしれませんが、1 つの拡張機能で複数の関数が作成される可能性があるため、これにより予期しない動作が発生する可能性があります。拡張機能をアンインストールする方法については、ドキュメントを参照してください。
アンインストールすると、すべてのリソース (拡張機能の関数など) と、拡張機能のそのインスタンス用に作成されたサービス アカウントが削除されます。ただし、拡張機能によって作成されたアーティファクト (サイズ変更された画像など) は、拡張機能をアンインストールした後もプロジェクトに残ります。
1 つのプロジェクトに拡張機能の複数のコピーをインストールする
プロジェクト内に特定の拡張機能の単一インスタンスをインストールすることに限定されません。別のパスのエントリを制限したい場合は、この拡張機能の別のインスタンスをインストールできます。ただし、このコードラボでは、拡張機能を 1 回だけインストールします。
実際の動作を確認してください
- 木琴またはラテの投稿に使用したアカウントでログインしていることを確認してください
- いくつかの下書きを生成します。
- アプリの右下隅にある「何かを販売」ボタンをクリックします
- タイトルを編集して「ドラフト 1」とします。
- 「下書き」セクションまで下にスクロールし、下書きの数を表示します。少なくとも 2 つあるはずです。
- 上部のアプリバーにある「FRIENDLY MARKET」ボタンをクリックします。この方法では、下書きが保存されますが、投稿する必要はありません。
- 「ドラフト 2」、「ドラフト 3」など、「ドラフト 6」まで繰り返します。
- 「ドラフト 6」を作成すると、「ドラフト 1 がドラフトセクションから消えます。
- Resize Images 拡張機能の場合と同様に、関数ログをチェックして、どの関数がトリガーされたかを確認できます。
保持できる下書きの制限が小さすぎます
カスタマー サポート チームから連絡があり、最も多作な販売者の中には、下書きが投稿前に削除されてしまうと苦情が寄せられているとの連絡がありました。チームメイトと計算を確認すると、計算が 10,000 倍も違っていたことに気づきました。
どうすればこれを修正できますか?インストールした拡張機能を再設定してみましょう!
- Firebase コンソールの左側のペインで、 [拡張機能]をクリックします。
- インストールされた拡張機能のカードで、 「管理」をクリックします。
- 右上隅にある[拡張機能の再構成]をクリックします。
- [保持するノードの最大数]を
50000
に変更します。 - 「保存」をクリックします。
やるべきことはこれだけです。拡張機能の更新にかかる時間内に、サポート チームに連絡して、修正がすでに展開されていることを知らせることができます。
6. ユーザーデータの自動削除
問題
カスタマー サポート チームから再度連絡がありました。アカウントを削除した販売者は依然として他のユーザーからメールを受信しており、彼らは怒っています。これらの販売者は、アカウントを削除すると自分のメール アドレスもシステムから削除されることを期待していました。
今のところ、サポートは各ユーザーのデータを手動で削除していますが、もっと良い方法があるはずです。あなたはそれについて考え、定期的に実行して削除されたアカウントから電子メール アドレスを消去する独自のバッチ ジョブを作成することを検討します。しかし、ユーザーデータの削除は非常に一般的な問題のようです。 Firebase Extensions もこの問題の解決に役立つかもしれません。
ソリューション
ユーザーがアカウントを削除したときにデータベース内のusers/uid
ノードを自動的に削除するように、ユーザーデータの削除拡張機能を構成します。
- 拡張機能の詳細ページで「インストール」ボタンをクリックします。
- マーケットプレイス ウェブ アプリに使用している Firebase プロジェクトを選択します。
- 「拡張機能の構成」ステップに到達するまで、画面上の指示に従います。
- Realtime Database のパスには、
sellers/{UID}
と入力します。sellers
部分は、その子にユーザーの電子メール アドレスが含まれるノードであり、{UID}
はワイルドカードです。この構成を使用すると、拡張機能は、UID 1234 を持つユーザーが自分のアカウントを削除すると、データベースからsellers/1234
削除する必要があることを認識します。 - 「拡張機能のインストール」をクリックします。
インストールが完了するのを待っている間...
カスタマイズ性について話しましょう
このコードラボでは、Firebase Extensions が一般的なユースケースの解決に役立つことと、アプリのニーズに合わせて拡張機能を構成できることがわかりました。
ただし、拡張機能ですべての問題を解決できるわけではなく、ユーザー データの削除の問題はその良い例です。ユーザー データの削除拡張機能は、ユーザーがアカウントを削除した後も電子メールが公開されたままであるという現在の苦情に対処しますが、この拡張機能はすべてを削除するわけではありません。たとえば、商品リストは引き続き利用可能で、Cloud Storage 内の画像もそのまま残ります。ユーザー データの削除拡張機能を使用すると、削除する Cloud Storage パスを構成できますが、ユーザーはさまざまな名前を持つさまざまなファイルをアップロードできるため、これらのアーティファクトを自動的に削除するようにこの拡張機能を構成することはできません。このような状況では、アプリのデータ モデルに固有のコードを作成できるCloud Functions for Firebase の方が適している可能性があります。
延長と課金
Firebase 拡張機能自体は無料で使用できます (使用した基盤となるリソースに対してのみ料金が発生します) が、拡張機能に必要な基盤となるリソースの一部には課金が必要な場合があります。このコードラボは、請求先アカウントなしで完了できるように設計されています。ただし、Flame または Blaze プランを設定すると、多くの非常に興味深い Firebase 拡張機能のロックが解除されます。
たとえば、 URL の短縮、メールのトリガー、 BigQuery へのコレクションのエクスポートなどを行うことができます。拡張機能の完全なカタログはここで確認してください。
欲しい拡張機能があり、現在は利用できない場合は、ぜひお知らせください。新しい拡張機能を提案するには、 Firebase サポートに機能リクエストを提出してください。
実際の動作を確認してください
拡張機能のインストールが完了したら、ユーザーを削除して、何が起こるかを確認します。
- Firebase コンソールで、 Realtime Databaseダッシュボードに移動します。
-
sellers
ノードを展開します。 - 各販売者の情報は、ユーザー UID に基づいてキー化されます。ユーザーの UID を選択します。
- Firebase コンソールで、認証ダッシュボードに移動し、そのユーザー UID を見つけます。
- UID の右側にあるメニューを展開し、 [アカウントの削除]を選択します。
- Realtime Databaseダッシュボードに戻ります。販売者の情報が消えてしまいます!
7. おめでとうございます!
このコードラボではあまりコードを記述しませんでしたが、マーケットプレイス アプリに重要な機能を追加しました。
拡張機能を検出、構成、インストール、再構成する方法を学習しました。さらに、インストールされている拡張機能を監視する方法と、必要に応じてそれらをアンインストールする方法についても学習しました。
次は何ですか?
他の拡張機能をいくつかチェックしてください。
- Cloud Firestore でテキスト文字列を翻訳する(請求先アカウントが必要)
- 新しいユーザーを Mailchimp メール リストに追加します(請求先アカウントが必要です)
- 短縮 URL (請求先アカウントが必要)
さらにカスタムのサーバー側コードが必要ですか?
その他の役立つドキュメント
拡張機能の管理:
- Firebase CLI を使用して拡張機能を管理してみる
- 予算アラートを設定する
- インストールされた拡張機能が実行される頻度を確認する
- インストールされている拡張機能を新しいバージョンに更新する
- 拡張機能をアンインストールする
拡張機能についてさらに詳しく学習するには: