【障害】ローカルストレージの会員認証データが消えた【ごめんなさい】

【障害】ローカルストレージの会員認証データが消えた【ごめんなさい】

※ 本ページにはアフィリエイト広告(PR)が含まれます。

こんにちは、Stacaの開発者です。

公開しているアプリで、かなり致命的なバグを出してしまいました。

フレームワークのメジャーアップデート対応中に、アプリのローカルストレージに保存されていた会員認証データが消えてしまい、スタンプカード情報が表示されなくなったのです。

被害を受けられた方、本当に申し訳ございません。


1.会員認証データが消えたら何がヤバいのか


Stacaでは初回の会員登録時にローカルストレージに認証情報を保存しています。これは次回以降のアプリ起動時に自動ログインできるようにするためです。

※ 「そもそもStacaって何?」という方はこちらを先にお読みください

ローカルストレージには

  • メールアドレス会員の場合は「メールアドレス」と「パスワード」
  • 匿名会員の場合は「ニフクラmobile backend」で生成される認証キー(authData)

を保存していました。

今回、アプリにバグがあり、ローカルストレージの認証情報が消失してしまったのです。

メールアドレス会員の場合は「メールアドレス」と「パスワード」を再入力してもらえばログインできるため、「一度だけ自動ログインができない」というだけでそれほど大きな影響はありませんでした。
ニフクラ mobile backend メールアドレス認証

しかし、匿名会員の場合はユーザーには見えないローカルストレージに保存している「認証キー」が消えてしまったので、ログインすることができなくなってしまいました。
ニフクラ mobile backend 匿名認証

Stacaにログインできないということは、お客さまがコツコツ貯めたスタンプカードの情報を見ることができなくなるということです。スタンプを貯めることもできなければ、利用できるはずの特典も利用できません。

さらにはお店(ショップユーザー)の場合はもっと深刻です。昨日まで見えていたお客様のスタンプカード一覧が表示されなくなるのです。

お客さまがカードを提示しているのに、お店側でスタンプを押せないのです。もちろん、お店側で特典を利用済み状態にすることもできません。

お店によっては「スタンプが一杯になったら1000円割引」とか「次回サービス料が無料」といった特典を設けておられます。

お店やお客さまにとって、スタンプカードはお金と同じ価値があるということです。それが突然、アプリから消えてなくなるんです。

思い出しただけでイヤな汗が出てきました。

2.そもそもアプリをアップデートした経緯


Monacaをはじめとするハイブリッドアプリ開発フレームワークの基盤であるApache Cordovaが大規模なメジャーアップデートを実施しました。

2024年以降、クロスプラットフォーム開発の選択肢は多様化しており、Flutter、React Native、Capacitorなど様々なフレームワークが選択肢として存在します。ただし、既に構築されたMonacaベースのアプリケーションについては、Apache Cordovaの継続的なメンテナンスが必要不可欠です。

Cordovaのバージョンアップはかなり厄介で、JavaScriptエンジンの変更、ネイティブプラグインの互換性問題、セキュリティ要件の更新など、何もソースコードを変更していないのにアプリが動かなくなることがあります。特にiOS開発では、Appleの要件変更に伴うUIWebViewからWKWebViewへの移行など、複数世代にわたる重大な仕様変更が存在してきました。

できるだけ先送りにしたかったのですが、Monacaの公式デバッガーがメジャーバージョンアップされてしまい、古いバージョンのアプリ開発ができなくなったんですね。

それで仕方なくアプリをメジャーアップデート対応することにしました。

・・・これが不幸の始まりでした。

メジャーアップデート直後、予想通り動かなくなるアプリ。実機でテストしてもスプラッシュスクリーンのまま固まっています。

デバッグツールのログを調べてみると、アプリ初期化時にプラットフォーム機能が使える状態になったら呼ばれるはずのコールバック関数が呼ばれていない模様。

試しに怪しそうなプラグインをアップデートしてもダメ、削除してもダメ。GitHubのIssueを漁ったり、Stack Overflowで類似事例を探したり、次々と試行錯誤を繰り返しました。

ええい、何が原因か分からないから、いったん全部のプラグインを外してしまおう!
(今思えばこれが悪かった・・・)

しかし、それでもアプリが動くことはありませんでした。

かれこれ2ヶ月以上は技術調査を続けましたが、原因は分からず、「もうこの先アプリをアップデートできないんじゃないか」という絶望感に襲われていたころ、Stack Overflowのフォーラムで関連する情報にたどり着きました。

【stack overflow】Cordova DeviceReady not firing

簡潔に言うと、HTMLドキュメントのhead要素内にCordovaローダースクリプトの読み込み記述が必要だというものでした。

<script src="cordova.js"></script>

かなり古い情報でしたし、前のバージョンではこの記述がなくても動いていたので、「どうせまた駄目だろうな」と思いながらも試したところ、、、なんと動きました!

※ 実際に追加したのはMonacaの環境に合わせたこの1行です

<script src="components/monaca-cordova-loader/cordova-loader.js"></script>

「よかった、これでようやくアプリをアップデートできる・・・」

苦労していた期間が長かった分、達成感もひとしおです。

調査のために削除していたプラグインをもう一度、全部入れ直して、そそくさとアプリを本番環境にリリースしました。

ひとつだけ、とても重要なプラグインを入れ忘れたまま。。。

3.あれ、バグったかも、と気付いた瞬間


リリース後、念のためアプリに導入しているプラグインの一覧を確認していたところ、「cordova-plugin-migrate-localstorage」が含まれていないことに気づきました。

このプラグインは、かつてiOS開発における仕様変更時(UIWebViewからWKWebViewへの移行。2023年12月でUIWebViewのサポートが完全終了)に、ローカルストレージのデータをシステム上の異なるパスへ自動的に移行するために実装されたものです。2026年現在では、ほとんどのiOSアプリがWKWebViewベースで動作していますが、既存データマイグレーション対応には依然として重要なコンポーネントです。

CordovaのUIWebView→WKWebView移行についてまとめ

「ん?このプラグインがないとデータが古いパスを参照しているんじゃないか?」
「そのパスには認証データは存在しないぞ。。。」

ここで、はじめて本当の障害に気づきました。

認証データが見つからないということは、匿名会員がログインできないということです。
ログインできないということはスタンプカードも見えなくなっているということです。

これはヤバい!

急いでプラグインを再度インストールして修正版のアプリをリリースしました。

でも不具合のあったバージョンを使用していたユーザーの認証データは既にローカルストレージから消えていたのでした。

どうしよう。。。

4.予想通り、問い合わせメールが来た・・・


悩んでいるうちにユーザーから続々と問い合わせメールが届き始めました。

会員登録せずに利用してたのですが履歴がきえてるのですがどうしたらいいですか?


ショップユーザーとして使用しておりましたがログインできなくなりました。
何かログイン方法ありますか?


あわわわ、なんとかせねば。

ただし、消えたのはスマートフォン端末上のローカルストレージのデータなので、サーバ側からは復旧のしようがありません。モダンなバックエンド環境(Firestore、DynamoDB、Supabase等)では、サーバサイドのデータはログをたどって復旧可能ですが、端末側のローカルストレージの喪失は難しいのです。

さてどうするか。。。

一つの妙案が浮かびました。

「そうだ!バックエンドサーバに保存されている認証キーをローカルストレージに復元すればいいんじゃないか」

5.ありったけの知恵を絞って復旧にいそしむ


「ニフクラmobile backend」の会員データベースには「userName」と認証キー「authData」が保存されています。

「userName」はシステムで自動付与されるユニークかつランダムな文字列です。

なので、

  • 問い合わせメールをくれたユーザーに「userName」をお知らせします
  • ユーザーが「userName」をアプリに入力すると、バックエンドから認証キー「authData」を取得してローカルストレージに保存し直す仕様に変更

この対応でなんとかなりそうです。

早速、データ復旧専用の画面をアプリに実装して即日リリース。その後は問い合わせメールが来るたびに、ユーザーに「userName」をお知らせして復旧対応をする日々が続きました。

最終的には、復旧対応も10件程度で済み、本番環境での障害は無事に収束したのでした。

6.教訓


フレームワークやライブラリをメジャーアップデートする際の検証は、最初から最後まで入念に実施すること。

今回はアップデート対応の最大の課題が解決して安心していた、ということが一因ではありますが、メジャーバージョンアップ後のアプリを本番環境にリリースする前に、プラグイン(機能拡張モジュール)の漏れやデータ永続化の問題まで、くまなく検証すべきでした。

現在の開発環境では、以下のようなベストプラクティスが一般的です。

  • 自動テストスイート(ユニットテスト、統合テスト)による継続的検証
  • ステージング環境での十分な期間のテスト(最低1-2週間)
  • CI/CDパイプラインによる自動ビルド・デプロイ検証
  • ローカルストレージ、セッション管理、認証情報の検証チェックリスト化

特にローカルストレージやセッション管理、認証情報のようなアプリの根幹に関わるコンポーネントについては、あくまで慎重に、チェックリスト化して一つずつ確認する必要があります。

障害に気づいてからは、生きた心地がしませんでしたが、ユーザー様への影響は最小限で済んでよかったと思います。

最後に、データ復旧の案内をしたユーザー様からは、

スタンプカードが見れるようになりました。ありがとうございました!


ログインできました。助かりました。復旧ありがとうございます。


という、温かいメッセージをいただきました。

アプリの不具合が原因なのに、本当に申し訳ない気持ちでいっぱいです。
ご迷惑をかけた皆様、本当に申し訳ありませんでした。

今後はバグを出さないよう、特にメジャーアップデート時には十分な検証期間を設けて、自動テスト、段階的なデプロイ、ロールバック計画など、現代的なDevOpsプラクティスを活用し、くれぐれも気をつけます!

ITエンジニアのキャリアアップを検討しているなら

レバテックキャリアに無料登録

PR




PR


HOME スマホアプリ開発ブログ SE入門講座 プログラミングスクール フリーSE案件サイト SEおすすめ書籍