Dart あるいは Firebase Admin SDK のない言語でユーザー管理
Dart で Firebase Auth のユーザー情報を取得したり、ユーザーを削除したかったのだけど、Firebase Admin SDK は Dart では提供されていなくて困った。REST API の仕様も正式に公開されていない。
調べたら、Firebase Auth の認証機構は Google IdentityToolkit と統合されていて、IdentityToolkit の REST API を使うことで Firebase Admin SDK 相当の操作ができることがわかった。 IdentityToolkit のクライアントは googleapis のパッケージで提供されているので、それを利用すればOK。
ユーザー情報の取得
import 'package:googleapis/identitytoolkit/v3.dart'; import 'package:googleapis_auth/auth.dart'; import 'package:googleapis_auth/auth_io.dart'; void main() async { final credentials = ServiceAccountCredentials.fromJson("service_account.json の内容"); final httpClient = await clientViaServiceAccount( credentials, ['https://www.googleapis.com/auth/identitytoolkit']); final identityToolkit = IdentitytoolkitApi(httpClient); final relyingParty = identityToolkit.relyingparty; final request = IdentitytoolkitRelyingpartyGetAccountInfoRequest() ..localId = ["UID"]; final response = await relyingParty.getAccountInfo(request); print(response.users[0].name); print(response.users[0].email); }
ユーザーの削除
import 'package:googleapis/identitytoolkit/v3.dart'; import 'package:googleapis_auth/auth.dart'; import 'package:googleapis_auth/auth_io.dart'; void main() async { final credentials = ServiceAccountCredentials.fromJson("service_account.json の内容"); final httpClient = await clientViaServiceAccount( credentials, ['https://www.googleapis.com/auth/identitytoolkit']); final identityToolkit = IdentitytoolkitApi(httpClient); final relyingParty = identityToolkit.relyingparty; final request = IdentitytoolkitRelyingpartyDeleteAccountRequest() ..localId = "UID"; await relyingParty.deleteAccount(request); }
2020-03-30 一日の過ごし方
コロナウィルスの感染拡大で先週の金曜から再びリモート体制。
リモートワークは意識的にオン・オフを切り替えたり、心身を整える必要がある。以下の記事を参考に、自分も仕事を始める前の散歩と昼食後の仮眠をやっている。散歩は特におすすめで、外に出てしばらく太陽の光を浴びることでシャキッとする。あとは自分なりにオン・オフを切り替える儀式のようなものが必要だと考えていて、自分は服をちゃんと着替えるというのをそれにしている(他にもハチマキを付けるとか色々ありそう)。
作業はずっと集中し続けると後でくる反動がキツいので、40分集中・10分休憩のルーティンをまわしている。40分の集中にちょうどいいのが、チャイコフスキーの交響曲で、はじめはゆっくりのテンポで慣らして、終楽章のアップテンポで追い込める良さがある。4番、5番、6番をリピートして聞いている。だんだん飽きてきたので、レパートリーを増やしたい。
リモートワークの作業のメリハリつけるのに交響曲聞くのがありな気がしてきた。1回40分、第1楽章のゆっくりのテンポから始まって終楽章は早いテンポで追い込める。曲が終わったら休憩(今日はチャイコフスキーの4から順に聞いてる)
— kitak / KITA Keisuke (年中無休でグルグルアーム) (@kitak) 2020年3月27日
タイプセーフに Future.wait したい
最近、お仕事で Dart を書いている。Dart では非同期処理を JavaScript の Promise に似た Future という概念で扱うことができて、複数の非同期処理を扱うには、JavaScript の Promise.all と同等な Future.wait という API が用意されている。
Future.wait の引数の配列の Future の型が同じ場合は問題ないが、異なる場合は共通の基底クラスにキャストされて型情報が失われてしまう(TypeScript の Promise.all でも同じはず)。
例えば、以下のようなコードで、callFoo
が Future<Foo>
, callBar
がFuture<Bar>
を返すとすると、results
の推論された型は List<Object>
になる(Foo
とBar
が共通の親を持っている場合はObject
ではなく、その親になる)。
final results = await Future.wait([callFoo(), callBar()]);
こんなかんじでダウンキャストすればいいんだけど、Future オブジェクトの数が増えてくるとうっかり間違えて実行時エラーを起こしてしまいそう。
final foo = results[0] as Foo; final bar = results[1] as Bar;
いまいまは、await しているスコープであらかじめ変数を宣言しておいて、各 Future オブジェクトの then で代入するのがいいかなぁ、と思っている。Future.all を await した結果は使わず、ただ待つだけ。
Foo foo;
Bar bar;
await Future.wait([
callFoo().then((f) { foo = f; }),
callBar().then((b) { bar = b; }),
]);
2020-03-22 胃腸炎から復帰
7日の夜に胃腸炎になって、しばらく省エネモードで生きていた。この日は久しぶりに身体の調子がいいかんじだった。
胃腸炎、前日の昼に食べたカキフライがよくなかったのか(少し生っぽいというか、磯臭いかんじだった)、夜に食べたあぶりレバー・センマイ刺しがよくなかったのか、それとも当日の昼に食べた焼き肉がよくなかったのか(無意識でトングで取り皿にお肉を運んでいた気がする。箸で取りましょう...)。去年の今頃も、生焼けのとんかつを食べて胃腸炎になっていた。年を重ねるごとに無理をすると(胃腸炎になる前から、体調がいまいちだった)一気に体調を悪くする確率が高くなっている気がする。意識的に養生する必要がある。
前々日にランニングを再開したのだけど、しばらく走っていなかったから足の筋力が落ちて、この日も筋肉痛が残っていた。ランニングはお休み
この日も恒例の朝活で外苑前へ。ここ数回はすぐに定員が埋まる。多分、コロナで朝活も自粛されていて、そこから人が流れているのかな。もくもく Elasticsearch の素振りをしていた。
終わった後は髪を切りに渋谷に行ったのだけど、4人待ちで1時間近く待つ必要があったので諦める。CONROWでグリーンカレー・ガイヤーンを食べて、本屋に少し寄って、帰宅。
家の最寄り駅に着いたところで、この前、ランニング中によさそうな美容院を見かけたことを思い出し、向かう。入ったら、すぐに切ってもらえた。担当してくれた人がやたら会話テクの高い人で、普段の仕事の話、作っているアプリの話、お子さんがハマっているYouTuberの話など。話している間にあっという間に終わった。前のところより、少しだけ高いけど、カットの手際がよくて気持ちいいし、仕上がりもよかったので、次もここにしようかな、という気持ち。渋谷にいく理由がまたひとつ減ってしまった。
家に帰って、3月場所の千秋楽を見る。朝乃山が貴景勝に勝って、大関昇進をほぼ確実にしたのがうれしかった。今場所はコロナウィルスの影響で無観客の異例の場所だけれども、千秋楽の取り組みが終わった後の式事?も普段と違って新鮮だった。普段は中継されない出世力士手打ち式や神送りの儀式が見れたり。相撲の神事としての面が強く出た場所だったと思う。
2020-02-29 もつ焼きばん
起きて、本を読んだり、コードを書いたり。BLUE GIANT SUPREME の最新刊が配信されていたので読む。今回も非常に良かった。思えば遠くに来たもんだ、的なエピソードで読者の心を揺さぶりにくる。
BLUE GIANT SUPREME (10) (ビッグコミックススペシャル)
- 作者:石塚 真一
- 発売日: 2020/02/28
- メディア: コミック
昼前にリングフィットを17分、フィットボクシングを35分。さらにジョグ。流石にワークアウトを3種類やるとちょっときつい。トータル一時間程度に済むようにバランスよくやっていく。
夕方に祐天寺のもつ焼きばんへ。定期的に飲む同じ北陸出身のSさんとSさんの同僚のMさんと飲む。もつ焼きは当然おいしいのだけど、ばんサラダもおいしい。カニカマが入ったサラダ、今度家でも作ってみようかな。
その後、いくつかお店を変えて、この日はトータルで4杯ぐらい飲んだ。そんなに酔ったつもりはなかったんだけど、相性が悪い酒があったのか翌日若干頭痛がした。
2020-02-24 アトレティコ、ビジャレアルに勝利
ラ・リーガ第25節アトレティコvsビジャレアルを見るために5時に起床、のつもりだったんだけど、例のごとく失敗して、6時ごろに起きる。この試合から怪我で離脱していたジョアン・フェリックスとトリッピアーが帰ってきた(ふたりともスタメンではなく控え)。シメオネがイエローカードの累積でベンチ入りできずで、アシスタント・コーチのブルゴスが指揮を執る(強面のおっかなさそうなおじさんだった)。
前半が終わって、1-1で同点。知らなかったんだけど、アトレティコはビジャレアルと通算対戦成績が互角だったらしい。これはバルサ、レアルに次ぐものらしくて、かなり意外(僕は今より強かった頃のビジャレアルを知らない)。
前半のハイライトから見始める。リヴァプール戦に比べて、相手へのプレッシャーが弱く、うまく噛み合っていない印象だった。交代でジョアン・フェリックスとトリッピアーが入ってから良くなって、トリッピアーの折り返しからアンヘル・コレアの上げたクロスにコケが合わせて、2点目。コケはこの試合、縦横無尽によく走っていた。その後にジョアン・フェリックスがダメ押しの3点目。復帰早々にゴールへの執着をみせてくれた。
終わってみれば 3-1。3点取って勝ったのすごい久しぶりな気がする... コケが戻ってきてから負け知らず。このチームは目立たないけれども縁の下の力持ちの中盤のコケとトーマスの存在が大きいことを思い知らされる。
この勝利で3位に浮上。CL圏を維持しつつ、バルサ、レアルを脅かしてほしい。
前日にあちこち移動して疲れたので、この日は家で過ごす。休日に家で過ごすとなると、あれもやりたい、これもやりたいとなって、結局、なにもせず終わることも多い。こういうときは、リストにやりたいことを書き出して、その中の3つをできればOKということにしている(3つでもけっこう多いけど...)。
本を読むときも似たような心構えを最近もっていて、本に書かれたことをすべておさえようとすると妙にハードルが上がって、読まずに積むことが多いので、最近は自分の思考、行動に良い影響を与えるものがひとつだけ得られればそれでよし、ということにしている(読む本にもよるけれど)。
結局、本を読んだり、英語の勉強をしたりしていた。
3時にポッドキャストの収録。ゲストが多いポッドキャストなのでお呼ばれするのは年に一回ぐらいなのだけど、相変わらず話すのうまくないなぁ...w 週一の朝活でもポッドキャストをやってみようか、という話がちょいちょい上がるので場数を増やしてみようかな。
クロスプラットフォームの技術選定の話をしていたのだけど、Flutter をプッシュしすぎたかなぁ、という気がしている。当然のことながら、絶対にこれという答えはなくて、組織のフェーズとか所属しているメンバーのバックボーンとかスキルにも依りますよね、という話をもっとすべきだった。例えば、React や Web フロントエンドのエコシステムに成熟した人がいる、かつ、iOS, Android エンジニア(あるいは経験者)がいるのであれば、React Native はかなりアリな選択肢だと思う。
収録が終わった後は打ち上げで焼肉 矢澤へ。いやー... 最高のお肉でした。口に入れて、咀嚼した瞬間になんていうのか幸せ物質みたいなのがドバッと出てきて、(いい意味で)もだえながらいただきました。
あと、例のごとく、お酒はハイボールとビールの二杯でちょうどいいかんじになった。家に帰った頃には酔いが抜けてたんだけど、まぁ、これぐらいが次の日にも残らなくてちょうどいいということで。
2020-02-23 文化浴泉
起きて、軽く30分ぐらいジョグ。なんとなく身体が重い。足の筋肉の疲労が溜まっているのかなぁ。
毎週恒例の朝活のために表参道へ。捗った。朝活をうまくやるコツは、移動中にTODOリストをつくっておいて、会場についたらすぐに手を動かすことができるようにすることな気がする。
終わった後は近くの中華料理店でランチ(お店の名前を忘れてしまった...)。牛肉チャーハンとワンタンスープのセットを食べた。牛肉チャーハンが自分が求めていたドンピシャな味でよかった。
髪が邪魔に感じたので、髪を切りに渋谷へ。前回から大体一ヶ月くらいかな。
免許更新が近いのだけど、メガネの度が合わなくなっていて視力検査をパスできるか怪しいのと鼻あてが取れたり、フレームにヒビが入ったのを応急処置でなんとかしていたので、メガネを買い換えることに。作るのに視力検査も含めけっこう時間がかかる印象があったので腰が重くなっていたのだった。実際やってみると空いていたのもあって、フレーム選びから会計まで30分程度で終わった。受け取りに一時間くらいかかるので、近くのカフェに入ってもくもくしていた。
メガネを受け取った後は久しぶりにCONROWへ。店員さんとコロナウイルスやフードデリバリーサービスの四方山話。ヤムウンセンとナムトックコームーヤーンを食べる。おいしかったけど、2つともハーブが入っている甘酸っぱいソースの料理なので、1つはカレーとかカオマンガイを攻めてもよかったのかなぁ、という気もした。
ご飯を食べた後は腹ごなしに池尻大橋まで歩いて、文化浴泉へ。冷温交代浴で足の疲労を抜く。
湯、サウナ、水風呂のセットを3セット。サウナはヒノキのいい香りがした。他所と比べて、サウナは熱く、水風呂はキンキンに冷たく、いいかんじ。3セットでちょっと物足りない気もしたけれど、これ以上やると逆に疲れそうな気がしたので、ほどほどなところで。
池尻大橋駅から帰宅。電車の中は爆睡していた。
家に帰った後は、英語の勉強を少しやって、寝る前にリングフィットアドベンチャーを20分、フィットボクシングを30分。
初めてやったバンザイスクワットがなかなかきつかった。しばらくはバンザイスクワットより負荷が低いワイドスクワットをメインでやって、少しずつ慣らしていく。
フィットボクシングはだいぶ慣れてきて、高いスコアが出せるようになってきたけれど、最近入ったダッキングとかの避ける動作でひざが痛く感じる。基本姿勢に問題があるのかなぁ。
リングフィット+フィットボクシングを始めて大体2週間くらい。起床時と寝る前に Withings に乗っているのだけど、体重は変化なし。ただ、体脂肪率は減少、筋肉量は増加の傾向がみえるので、継続していくぞ、というかんじ。