React Nativeを、ペーパープロトタイピング
とprottなどを使ったモックアッププロトタイピング
の次のフェーズとして動くプロトタイピングツール
に使えないかなぁと思ってちょこちょこ触ってます。
うまくいくと両ユーザ向けに同時に動くプロトタイプを提供できてフィードバックが捗るのとAndroid、iOSの両方のチームで同時に一つの仕様をいじれるので仮説や価値の理解や共有らなんやら色々捗るんじゃないかなぁとか思ってます。
バックエンド側もFirebaseを使うと結構カジュアルに色々やれそうだな〜とか思っていて色々試し始めたんですがFirebase Storageにデバイス上の画像をアップロードする処理ではまりました。
環境
- React Native: 0.42.3
- Firebase: 3.7.3
問題
react-native-image-pickerなんかを使って写真を撮ったりデバイス上の写真を選択すると、ファイル名やContentTypeやbase64に変換された実データを取得できます。次のコードはFirebase StorageにputString関数で画像をアップロードする例です。
firebase.initializeApp(config); const storage = firebase.storage().ref(); const ref = storage.child(response.fileName); const metadata = {contentType: response.type}; ref.putString(response.data, 'base64', metadata).then((snapshot) => { done(); });
putString関数の第一引数のresponse.data
には画像をbase64に変換した文字列が詰まっており、第二引数はデータフォーマットを示すためにbase64
を渡しています。これをReact Nativeで実行すると次のようにInvalid character found
となります。
どーもよくわからないのでBlobやUint8Arrayを使う方法を試みるも、そもそもReact NativeにはBlobはないらしいという事がわかり、react-native-fetch-blobというBlob周りのポリフィルを提供しているライブラリを導入して試してみるもうまくいかず途方にくれてました。
原因
万策尽きたのでしぶしぶFirebase Storageのクライアントコードを読むことにしました。エラー画面にstacktraceが吐かれてるのでそんなに追いかけるのは難しくなかったです。
こんな感じでtry-catchがあって、atob関数
しか呼び出してないのでこれがちゃんと動いてないんだな〜という事がわかりました。
対応
Blobを使ったりするところであれこれ試す中で、
javascript - How to convert base64 into Blob in React Native? - Stack Overflow
とかを試していたのでピンときて、
npm install --save base-64
して(base64)、
const atob = require('base-64').decode; window.atob = atob;
をコンポーネントの冒頭に書いたらうごいた。わいわい。
雑感
React Nativeのポリフィル集ありそうだけどどーなんだろ。 React.parts – A catalog of React componentsとかを眺めていると結構色々あって面白い。一方で改廃も激しいので大変そう。