☁️
[Unity]Firebase CloudStorageにて実機からファイルをアップロードする
背景
ドキュメントの方法でファイルをFirebase CloudStorageにアップロードしようとすると、Unityエディターからはアップデートできるが実機でエラーが出て失敗する。
エラー
CFURLResourceIsReachable failed because it was passed an URL which has no scheme
Firebase.Storage.StorageException: No object exists at the desired reference
対応
エラー文に書いてありますが、原因は指定した引数にschemeが付いてないからですね。
元々のコードはこんな感じでした。
public void UploadImageAsync(string localFilePath,int userId,Action<string> onComplete)
{
// localFilePathはApplication.persistentDataPath + file名
var fileName = $"xxxxxxx";
var imageRef = StorageRef.Child($"{fileName}.png");
var metadataChange = new MetadataChange {ContentType = "image/png"};
imageRef.PutFileAsync(localFilePath,metadataChange).ContinueWith(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
STDebug.Log(task.Exception.ToString());
onComplete.Call(null);
}
else
{
onComplete.Call(fileName);
}
});
}
ここでlocalFilePathにはApplication.persistentDataPathとfile名を結合したものが入っていました。
UnityEditor上だとこれでちゃんとアップロード完了します。
実機でもちゃんとアップロードできるようにするには、
file://
をパスの前につける必要があります。
private static string UriFileScheme = Uri.UriSchemeFile + "://";
protected virtual string GetFileUri(string filepath) {
if (filepath.StartsWith(UriFileScheme)) {
return filepath;
}
return String.Format("{0}{1}", UriFileScheme, filepath);
}
public void UploadImageAsync(string localFilePath,int userId,Action<string> onComplete)
{
var fileName = $"xxxxxxx";
var imageRef = StorageRef.Child($"{fileName}.png");
var metadataChange = new MetadataChange {ContentType = "image/png"};
// FilePathではなくUriを指定するようにする
var localFileUri = GetFileUri(localFilePath);
imageRef.PutFileAsync(localFilePath,metadataChange).ContinueWith(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
STDebug.Log(task.Exception.ToString());
onComplete.Call(null);
}
else
{
onComplete.Call(fileName);
}
});
}
こんな感じで指定すれば動くようになりました。
Editor上では動くもんだから原因の特定に1時間くらいかかってしまった...。
参考:
余談
自分のアプリでいうと
・大喜利オンラインの画像投稿機能
・定時退社オンラインの引き継ぎ機能
でこれを使おうと思っていたので助かりました。
Discussion