質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Storage+

Storage+は、IT業界団体CompTIA認定の資格で、ストレージに関する知識を証明します。ストレージの設計・構築~運用・管理までの知識を評価し、接続時のトラブルシューティングや基礎的なストレージ・システム管理のスキルを取得している証明になります。

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1436閲覧

【Vue x Storage】プロフィール画像を選択後、選択した画像を表示させたいです。

TMTN

総合スコア53

Storage+

Storage+は、IT業界団体CompTIA認定の資格で、ストレージに関する知識を証明します。ストレージの設計・構築~運用・管理までの知識を評価し、接続時のトラブルシューティングや基礎的なストレージ・システム管理のスキルを取得している証明になります。

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/05/19 05:51

編集2021/05/31 22:58

#プロフィール画像を選択後、リアルタイムで選択した画像を表示させたいです。

「プロフィール画像を編集する」を押下してアップロードする画像を選択後、
既存画像から(選択されていない場合デフォルト画像にしてます)選択された画像に切り替えたいです。
しかし、現状は切り替わらず「更新ボタン」を押下して発火させた後、プロフィール画面での表示は
きちんと表示されますが「更新ボタン」を押すまでは編集画面では選択画像が変わらない状態です・・

イメージ説明

#試したこと
以下のようにimg内を:src="preview"とするとdata内にで初期画像をデフォルト画像にしているので
プロフィール編集画面では常に初期画像を参照してしまうのですが、画像を選択した際
実装したい挙動になり、画像選択後はすぐに選択された画像に切り替わってくれます。

<img :src="preview" width="200 height="200" class="profile-img" alt="プロフィール画像"/>

プロフィール画像が選択されていない時はデフォルト画像を初期画像として表示して
画像選択されたらプロフィール編集画面で瞬時に選択後切り替えたいです。。

説明がわかりにくくて大変申し訳ございませんが、分かる方いらっしゃいましたら
お力添えをいただきたいです。

よろしくお願い致します。

#実際のコード

<template> <div> <Header /> <div class="mypage flex"> <div class="mypage-inner flex"> <div class="profile-inner-l flex"> <img class="profile-inner-l-img" :src="uploadedImage == '' ? preview : uploadedImage.fileUrl" alt="プロフィール画像" /> <div class="profile-inner-l-name txt">{{ profileData.name }}</div> </div> <div class="profile-inner-r flex"> <div class="item-inner"> <div class="post"> <div class="txt">{{ listData.length }}</div> <p>POSTS</p> </div> <div class="bookmark"> <div class="txt">{{ bookmarkList.length }}</div> <p>BOOKMARK</p> </div> </div> <hr class="separate" /> <button @click=" show(); openModal(); " class="profile-edit flex" > プロフィール編集 </button> <modal class="modal-inner" v-scroll-lock="open" name="edit" :width="1100" :height="740" > <div data-modal="edit" aria-expanded="true" class="vm--overlay"> <div class="vm--top-right-slot"></div> </div> <div class="modal-header flex"> <h2 class="profile-tll flex">プロフィールを編集する</h2> <hr class="separate" /> </div> <div class="modal-body"> <div class="profile-inner flex"> <div class="profile-contens flex"> <div class="profile-img-inner flex"> <img :src=" uploadedImage == '' ? preview : uploadedImage.fileUrl " width="200" height="200" class="profile-img" alt="プロフィール画像" /> <label class="profile-txt profile-update"> プロフィール画像を編集する <input type="file" @change="onFileChange" style="display:none" /> </label> </div> <div class="line"></div> <div class="profile-items flex"> <div class="profile-contens flex"> <input type="text" class="profile-item" placeholder="名前" v-model="name" /> </div>  ~ 省略~ <button class="hide-btn flex" @click=" hide(); closeModal(); " > × </button> </div> <button @click="updateBtn" class="update-btn flex"> 更新 </button> </div> </div> </modal> </div> </div> <div class="profile-list"> <ul class="list-item"> <li class="list-items"> 性別: <div class="list-color">{{ profileData.sex }}</div> </li>  ~ 省略~ </template> <script> import firebase from "firebase";  ~ 省略~ export default { data() { return { name: "", sex: "", sexs: [{ name: "男性" }, { name: "女性" }, { name: "その他" }],  ~ 省略~ ], favMovie: "", uploadedImage: "", profileData: {}, //配列にしないようにする。 listData: [], paginate: ["paginate-listData", "paginate-bookmarkList"], bookmarkList: [], open: false, file: "", preview: require("../assets/デフォルトの画像.jpg"), }; }, components: { Header, List, }, methods: { onFileChange(e) { const image = e.target.files; //選択された画像ファイルを選択 this.file = image[0]; //画像ファイルを1つだけ選択 // Firebase storageに保存するパス乱数で決めてthis.uploadUrlへ代入 const S = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const N = 16; this.uploadUrl = Array.from(crypto.getRandomValues(new Uint32Array(N))) .map((n) => S[n % S.length]) .join(""); let self = this; let fileReader = new FileReader(); //FileReaderは、Fileオブジェクトからデータを読み込むことのみを目的としたオブジェクト fileReader.onload = function() { //fileReader.onloadは、読み込みが正常に完了した時に発火するイベント self.preview = fileReader.result; //fileReaderの結果をself.previewへ代入 //関数の中ではfileReaderの[this]を参照してしまうため、一旦[self]に代入して、[this.]の代わりに[self.] とする }; fileReader.readAsDataURL(this.file); //this.fileの値をデータURLとして読み込み、488行目が発火する。 }, // updateBtn()が押下されたら、dbインスタンスを初期化して"posts"という名前のコレクションへの参照 updateBtn() { this.$swal({ title: "内容確認", text: "この内容で更新しますか?", icon: "info", buttons: true, dangerMode: true, }) .then((willDelete) => { if (willDelete) { let uploadParam = {}; if (this.uploadUrl) { const uploadTask = firebase .storage() .ref(this.uploadUrl) //さっき決めたパスを参照して、 // .child(this.uploadUrl) .put(this.file); //保存する uploadTask.then(() => { uploadTask.snapshot.ref.getDownloadURL().then((fileUrl) => { //this.fileに保存されたrefを参照してファイルのダウンロード URL を取得して、fileUrlへ代入。 const uploadedImage = { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), }; console.log(fileUrl, this.uploadUrl) uploadParam = { uploadedImage: uploadedImage }; //uploadParamへuploadedImageを代入。 const currentUser=firebase.auth().currentUser; currentUser.updateProfile({ photoURL : fileUrl }) .then(()=>{ }) }); }); } firebase //画像をfirestoreに保存 .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, access: this.access, selfpr: this.selfpr, profession: this.profession, genre: this.genre, favMovie: this.favMovie, ...uploadParam, time: firebase.firestore.FieldValue.serverTimestamp(), //サーバ側で値設定 }, { merge: true } //set()でmergeをtrueにすると、上書き。updetaと同様。 ); this.$swal("更新しました。", { icon: "success", }); // this.$router.go({ // path: `/mypage/${this.$route.params.uid}`, // force: true, // }); //プロフィール編集されたらページをリロード } else { this.$swal("キャンセルしました。"); } }) // .catch(() => { // this.$swal("更新出来ませんでした。", { // icon: "error", // }); // }); },  ~ 省略~ }, created() { const currentUser = firebase.auth().currentUser; this.uid = currentUser.uid; if (currentUser) { firebase .firestore() .collection("users") .doc(this.$route.params.uid) .get() .then((snapshot) => { this.profileData = snapshot.data(); this.name = this.profileData.name || ""; this.sex = this.profileData.sex || ""; this.age = this.profileData.age || ""; this.access = this.profileData.access || ""; this.selfpr = this.profileData.selfpr || ""; this.profession = this.profileData.profession || ""; this.uploadedImage = this.profileData.uploadedImage || ""; this.genre = this.profileData.genre || ""; this.favMovie = this.profileData.favMovie || ""; //全てのデータを取得して、profileDataへ代入。 }); }  ~ 省略~ }; </script>

#追記2

イメージ説明イメージ説明
イメージ説明

#追加3

イメージ説明

#追記4

イメージ説明

#追記5

イメージ説明
プロフィール画像選択前

![イメージ説が9563d0fae34ce1c21bb078978b152.png)
プロフィール画像選択後

イメージ説明
「更新ボタン」押下後直後(アラート表示時)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

省略の部分にもよりますが、uploadedImageを定義しているものはdata(){}内に定義されていますでしょうか?
そちらを定義することでリアクティブに切り替わりそうな気がします。

投稿2021/05/29 12:18

m2l

総合スコア318

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TMTN

2021/05/29 12:38

ご回答ありがとうございます。 uploadedImage: "",という風にdata()内に定義はしております。 しかし、リアルタイムで画像が変わらずです・・
m2l

2021/05/29 12:51

そうなんですね。 そちらはconst uploadedImage ~ と記載されているものと被っており、thisで指定したuploadedImageに代入されていない気がするので、反映されていないのかなと思います。 previewの方にも代入されているみたいなので、 下記のimage表示するところを下記のようにしてみるのはいかがでしょうか? :src="uploadedImage == '' ? preview : uploadedImage.fileUrl" ↓ :src="preview"
TMTN

2021/05/29 13:24

試したところ画像選択後はすぐに選択された画像に切り替わってくれますが、保存がされない状況ですね。。
m2l

2021/05/29 13:36

そうなんですね。。 firebaseのストレージには画像アップロードされていますか? fileUrlとthis.uploadUrlをconsole.logとかで表示しながら追いつつどこで上手く行っていないかご教授頂けますと幸いでございます。
TMTN

2021/05/29 14:13

現状確認したところstorageに保存がされていない状況ですね。。 コードを修正させていただいたものを再度掲載致しましたが、どこが原因何かわからずでして・・
m2l

2021/05/29 14:38

かしこまりました。 console.logを出力していただけますでしょうか? 追加するところは下記記載いたしましたので、 デベロッパーツールでどのように出ているかご返信いただけますと有難いです。 const uploadedImage = { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), }; // ここにログ出し console.log(fileUrl, this.uploadUrl) uploadParam = { uploadedImage: uploadedImage };
TMTN

2021/05/29 17:05

m2l様 ご確認遅くなり申し訳ございません。。 ログを確認し、追記2に結果を掲載しましたのでご確認お願い致します。
TMTN

2021/05/29 17:19 編集

さらに画像を追加させて頂きました。 storageには保存はされておりました。お伝え内容に誤りがあり大変申し訳ございません。。 firestoreに保存がされていなかったため、firestore保存する際のコードに誤りがあるのかと思われますが、firestoreコード内にあるアラート「更新しました」は表示されます。 特にエラーも出てなく、試しに「画像は更新せず」、「性別と住所、年齢」のみ更新してみても firestoreには情報を更新され保存されていることを確認。こちらもエラーは特に出ませんでした。
m2l

2021/05/29 19:26

そうなんですね。保存は上手くいっていて何よりです。 少し全体像が見えないのでmypage.vueを全部貼り付けることは可能でしょうか?
TMTN

2021/05/29 20:03

全体コードは字数上載せれなかったため、一部省略としてますが、実際コードという欄にHTMLとjs部を載せましたのでご確認いただけると幸いです。よろしくお願い致します。
m2l

2021/05/29 20:13 編集

ありがとうございます。このような作りなんですね。 若干Fatコンポーネント気味な点や、Create時の代入など少しきになる部分もありますが、 まずは保存のところを見ていければと思います。 下記のような形でuploadedImageに代入するといかがでしょうか? const uploadedImage = { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), }; ↓ this.uploadedImage = { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), };
TMTN

2021/05/29 20:45

気になる点等今回初のvueでの作成のため、至らない点多々あると思うのでご指摘頂けると幸いです。。 以下のように変更しましたが、現状変わらず保存がされなかったです・・・ uploadParam = { uploadedImage: this.uploadedImage };でもthis.をつけました。 -------------------------------- this.uploadedImage = { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), }; console.log(fileUrl, this.uploadUrl) uploadParam = { uploadedImage: this.uploadedImage }; ------------------------------
m2l

2021/05/29 21:12 編集

いきなり詰め込みすぎるのは中々難しいところもございますので、 頭の片隅レベルで大丈夫でございますが、 コンポーネントを細分化してpropsで受け渡ししていくとデバッグもしやすく、 大規模になっても使い回しなどができて良いです。 アトミックデザイン等で検索していただけると、色々記事が載っています。 また、Createdの中で、this.hogeからthis.fugaに再代入していますが、データはなるべく統一した方が、 色々なところに代入して、予期せぬ反映を防いでいくとよいかなと思います。 thisでも反映されないとのことでしたので、firebaseで行なっている非同期部分の処理を見ていけたらと思います。 下記のようにconsole.logを出すと表示としてはどうなりますでしょうか? ---------------------------------------------- console.log(fileUrl, this.uploadUrl) uploadParam = { uploadedImage: uploadedImage }; //uploadParamへuploadedImageを代入。 const currentUser=firebase.auth().currentUser; currentUser.updateProfile({ photoURL : fileUrl }) .then(()=>{ }) }); }); } // ここにログを追加 console.log(this.uploadedImage) firebase //画像をfirestoreに保存 .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, ----------------------------------------------
TMTN

2021/05/29 21:22

アトミックデザインですね。少し調べましたがもっと細分化して使う方が綺麗にコードが書けますね。私のコードはすごいごちゃごちゃしてしまってますよね。。勉強になります。ご指摘いただきありがとうございます。参考にして少し細分化にしていきたいと思います。 コンソール追加して確認してみましたが、値が出力されない状況です。。 追記3に追加しましたのでご確認いただけると幸いです。
m2l

2021/05/29 21:39

追記のご提供ありがとうございます。 ログをご覧いただくと何も入っていない状態かと思いますが、 こちらはupdateTaskの実行を待つ前にfirebaseの保存処理が走っているため(非同期)と考えられます。 その場合thenで後続の処理を書いていく形になります。 下記の処理をuploadParam = { uploadedImage: uploadedImage }; の直後の処理として記載するといかがでしょうか? -------------------------------- firebase //画像をfirestoreに保存 .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, access: this.access, selfpr: this.selfpr, profession: this.profession, genre: this.genre, favMovie: this.favMovie, ...uploadParam, time: firebase.firestore.FieldValue.serverTimestamp(), //サーバ側で値設定 }, { merge: true } //set()でmergeをtrueにすると、上書き。updetaと同様。 ); ----------------------------------------
TMTN

2021/05/29 22:23

updateTaskの実行を待つ前にfirebaseの保存処理が走っているためだったのですね。。 コード位置を変更させるとfirestoreにはデータ格納されるようになりました。 しかし、まだプロフィール画像変更箇所でリアルタイムで画像が瞬時に変わらない状況です。 画像何も設定していない時はpreviewが参照されるので最初は画像がリアルタイムで切り替わりますが、firestoreにデータ格納されている状態で画像を選択(previewでなくhis.uploadedImageが入っている状態)するとリアルタイムで変わらないですね・・
m2l

2021/05/29 22:35

今回は状態管理をvuexなどで行っていないのでオブジェクトの変更検知がvue側にいっていないことが原因かと思われます。 下記の記事を参考にthis.uploadedImageに格納しているものをsetで行うようにしてみてはいかがでしょうか? https://qiita.com/tmak_tsukamoto/items/7623f458448fa7cd01c7
TMTN

2021/05/29 22:58

そういうことですね・・ 掲載いただいた記事を参考に以下のようにしてみましたが記述の仕方が誤っているのか上手くいきません・・ ----------------------------- this.$set(this.uploadedImage = { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), }); ---------------------------------
m2l

2021/05/29 23:08

この様な感じにしてみてはいかがでしょう? this.$set(this, "uploadedImage",{ fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), });
TMTN

2021/05/30 05:47

お返事遅くなり大変申し訳ございません。。 コードを書き換えたところ、「プロフィール画像を編集する」というボタンを押して画像を選択後は、画像はリアルタイムで切り替わらないですが、「更新」ボタンを押し、「更新しました」というアラートが出た直後に画像が切り替わることは確認できました。 (コードを書き換えるまではアラート直後も変化せず、手動で更新したら画像の切り替わりが確認できる状況でした)
TMTN

2021/05/30 06:22

m2l 様 今からお仕事で実装確認できる環境でなくなるため、以降の確認は明日のお昼前頃になります・・ご了承お願いいたます。。
TMTN

2021/05/30 21:10 編集

m2l 様 度々本当に申し訳ございません。 職場でコードを見直し挙動を確認していたところ コードをご教示頂き修正した中で一点現在おかしな挙動が発生しておりまして プロフィール情報([追記4] 赤で囲った箇所)のみを変更した場合、Firestoreに保存がされないようになってしまいました・・ (プロフィール画像(左側)、プロフィール情報(右側)も一緒に変更した場合、またはプロフィール画像(左側)のみ変更した場合は、Fireestorに保存されますが、プロフィール情報(右側)のみ変更した場合、保存されなくなってしまいました・・) おそらく if (this.uploadUrl) {}にて画像が選択されていない場合は、Firestoreのset()内を...uploadParam,としてプロフィール情報のみをFirestoreに保存。 画像が選択された場合は、 uploadParam = { uploadedImage: this.uploadedImage }として画像もFirestoreni保存させておりましが、 uploadParam = { uploadedImage: this.uploadedImage };の直後の if (this.uploadUrl) {}外にあったFirestoreに保存するコードを{}内に追加した為かなと考えております・・ しかし、uploadParam = { uploadedImage: this.uploadedImage };の直後にFirestore保存のコードを記述しないと保存されませんでしたが、プロフィール情報のみでも保存はできておりました。 if (this.uploadUrl) {}のコード内に誤りがあるのでしょうか。。 単純に if (this.uploadUrl) {}内にて、uploadParam = { uploadedImage: this.uploadedImage };の直後に入れる事でFirestoreの保存するようにしましたが、プロフィール画像が選択しなかった場合の分岐処理ができていないので、同じくしなかった場合のFirestoreに保存するコードを書かないといけないかもしれませんね。 私がuploadParam = { uploadedImage: this.uploadedImage };の直後にコードを追加する際にもともとのコードを消したことが問題だったかもです・・。
m2l

2021/05/30 21:08

ご返信遅くなり申し訳ございません。 少し見てみますね。 これから仕事のため夜ご返信いたしますのでどうぞよろしくお願い致します。
TMTN

2021/05/30 21:13

m2l 様 今送った文ですが、編集させて頂きましたがこちらにつきましては自身のミスで自己解決できそうです。 申し訳ございません・・ 画像をリアルタイムで切り替える際のコードだけ見直していただければ幸いです。。 お忙しい中本当に申し訳ございませんが、お時間があるときで構いませんので おねがいしたいです。。急かしてしまうようなこと大変申し訳ございません。。
m2l

2021/05/30 21:21

かしこまりました! 早い解決ができず、お手数をお掛け致しますが確認していきますので宜しくお願いします。
TMTN

2021/05/30 21:27

m2l 様 とんでもございません。 解決にご協力頂き本当に感謝の気持ちでいっぱいです。 本当にありがとうございます。 またお時間ある時にでも回答お待ちしております。 お仕事頑張ってください。
m2l

2021/05/31 10:58

ご返信遅くなり、申し訳ございません。 少し修正箇所が多いので、長文になります。 (こちらで検証できないので少し動かしてみて検証頂けますと幸いでございます) ---template部変更前 <img class="profile-inner-l-img" :src="uploadedImage == '' ? preview : uploadedImage.fileUrl" alt="プロフィール画像" /> ---template部変更後 <img class="profile-inner-l-img" :src="preview == '' ? uploadedImage.fileUrl : preview" alt="プロフィール画像" /> ---script部(data)変更前 preview: require("../assets/デフォルトの画像.jpg"), uploadedImage: "", ---script部(data)変更後 preview: "", uploadedImage: { fileUrl: require("../assets/デフォルトの画像.jpg"), time: null, }; ---script部(updateBtn)最後の処理 this.preview = "" ---script部(created)変更前 this.uploadedImage = this.profileData.uploadedImage || ""; ---script部(created)変更後 this.$set(this, "uploadedImage",this.profileData.uploadedImage || this.uploadedImage);
TMTN

2021/05/31 13:07

お返事遅くなり申し訳ございません。 長文で回答いただきありがとうございます。 変更箇所を変えましたが、一点のみわからず、 ---script部(updateBtn)最後の処理 this.preview = "" 上記ですが、下記のようにしたら良いのでしょうか・・? 度々確認申し訳ございません・・ -------------------------------------------------------------------------------------- uploadParam = { uploadedImage: this.uploadedImage }; //uploadParamへuploadedImageを代入。 firebase //画像をfirestoreに保存 .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, access: this.access, selfpr: this.selfpr, profession: this.profession, genre: this.genre, favMovie: this.favMovie, ...uploadParam, time: firebase.firestore.FieldValue.serverTimestamp(), this.preview = "" //サーバ側で値設定 }, { merge: true } //set()でmergeをtrueにすると、上書き。updetaと同様。 ); --------------------------------------------------------------------------------------
TMTN

2021/05/31 13:10

ちなみに上記の箇所を無視して他を変更したら何とリアルタイムで変更され、私のやりたかった挙動となりました・・。やっとの思いで実装できました。本当に感謝いたします。お忙しい中お時間をいただきまして本当にありがとうござました。。
TMTN

2021/05/31 13:41

もしお手数でなければ、先に解決をしてくださった「Storageに保存されなかった件」 実はテラテイルにて別で質問をさせていただいておりましたので、 そちらに下記コピペしてもらうだけで大丈夫ですのでそちらに回答をしてくださりませんでしょうか。 m2l 様の回答をベストアンサーとしたいと思いまして。 一応下記にページを掲載させていただきます。 ※誤って手違いで自身で一度自己解決としてしまい、回答が残っておりますが、 後で運営様より消していただく予定となってます。 -------------------------------------------------------------------------------------- updateTaskの実行を待つ前にfirebaseの保存処理が走っているため(非同期)、 uploadParam = { uploadedImage: uploadedImage };の直後の処理すると解決いたしました。 updateBtn() { this.$swal({ title: "内容確認", text: "この内容で更新しますか?", icon: "info", buttons: true, dangerMode: true, }).then((willDelete) => { if (willDelete) { let uploadParam = {}; if (this.uploadUrl) { const uploadTask = firebase .storage() .ref(this.uploadUrl) //さっき決めたパスを参照して、 // .child(this.uploadUrl) .put(this.file); //保存する uploadTask.then(() => { uploadTask.snapshot.ref.getDownloadURL().then((fileUrl) => { //this.fileに保存されたrefを参照してファイルのダウンロード URL を取得して、fileUrlへ代入。 this.$set(this, "uploadedImage", { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), }); console.log(fileUrl, this.uploadUrl); uploadParam = { uploadedImage: this.uploadedImage }; //uploadParamへuploadedImageを代入。 firebase //画像をfirestoreに保存 .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, access: this.access, selfpr: this.selfpr, profession: this.profession, genre: this.genre, favMovie: this.favMovie, ...uploadParam, time: firebase.firestore.FieldValue.serverTimestamp(), // this.preview = "" //サーバ側で値設定 }, { merge: true } //set()でmergeをtrueにすると、上書き。updetaと同様。 ); const currentUser = firebase.auth().currentUser; currentUser .updateProfile({ photoURL: fileUrl, }) .then(() => { }); // .catch((err)=>{ // console.log(err); // }); }); }); } firebase //画像をfirestoreに保存 .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, access: this.access, selfpr: this.selfpr, profession: this.profession, genre: this.genre, favMovie: this.favMovie, ...uploadParam, time: firebase.firestore.FieldValue.serverTimestamp(), //サーバ側で値設定 }, { merge: true } //set()でmergeをtrueにすると、上書き。updetaと同様。 ); console.log(this.uploadedImage); this.$swal("更新しました。", { icon: "success", }); // this.$router.go({ // path: `/mypage/${this.$route.params.uid}`, // force: true, // }); //プロフィール編集されたらページをリロード } else { this.$swal("キャンセルしました。"); } }) .catch(() => { this.$swal("更新出来ませんでした。", { icon: "error", }); }); }, -------------------------------------------------------------------------------------- URL:https://teratail.com/questions/339848
m2l

2021/05/31 17:29

解決できて良かったです! previewの一番最後に記載というのは、初期化をしたかった形なので下記のようにすると動くかと思います。 (もし面倒でなければ試してみてください。こちらを入れることで更新をキャンセルした場合を考慮した処理になります。) かしこまりました。 リンクの方に記載しますね! updateBtn() { this.$swal({ title: "内容確認", text: "この内容で更新しますか?", icon: "info", buttons: true, dangerMode: true, }) .then((willDelete) => { if (willDelete) { let uploadParam = {}; if (this.uploadUrl) { const uploadTask = firebase .storage() .ref(this.uploadUrl) //さっき決めたパスを参照して、 // .child(this.uploadUrl) .put(this.file); //保存する uploadTask.then(() => { uploadTask.snapshot.ref.getDownloadURL().then((fileUrl) => { //this.fileに保存されたrefを参照してファイルのダウンロード URL を取得して、fileUrlへ代入。 const uploadedImage = { fileUrl: fileUrl, time: firebase.firestore.FieldValue.serverTimestamp(), }; console.log(fileUrl, this.uploadUrl) uploadParam = { uploadedImage: uploadedImage }; //uploadParamへuploadedImageを代入。 const currentUser=firebase.auth().currentUser; currentUser.updateProfile({ photoURL : fileUrl }) .then(()=>{ }) }); }); } firebase //画像をfirestoreに保存 .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, access: this.access, selfpr: this.selfpr, profession: this.profession, genre: this.genre, favMovie: this.favMovie, ...uploadParam, time: firebase.firestore.FieldValue.serverTimestamp(), //サーバ側で値設定 }, { merge: true } //set()でmergeをtrueにすると、上書き。updetaと同様。 ); this.$swal("更新しました。", { icon: "success", }); // this.$router.go({ // path: `/mypage/${this.$route.params.uid}`, // force: true, // }); //プロフィール編集されたらページをリロード } else { this.$swal("キャンセルしました。"); } }) // .catch(() => { // this.$swal("更新出来ませんでした。", { // icon: "error", // }); // }); // ここに追加 this.preview = "" },
TMTN

2021/05/31 22:40

そういうことですね! それであれば必要であるので追加しておきました。 本当に解決できてよかったです。 m2l様のおかげです・・お忙しい中お時間割いて、 お力添えいただきありがとうございました。 完成まで引き続き頑張ります!
m2l

2021/05/31 22:45

いえいえ、お時間かけて申し訳ございませんでした。 がんばってください!
TMTN

2021/05/31 22:59 編集

お礼後に度々ご質問本当に恐縮なのですが、、画像を選択された時(プロフィール画像を編集のボタンを押下された時)はしたい挙動となりましたが、「更新されました」というアラート表示時は一度選択前の画像を戻ってしまうのは、どこかで処理が抜けているのでしょうか・・。 一応追記5に画像選択前と選択後、更新ボタン押下後の画像を追加しました。 全然お急ぎではないので、本当にお時間に余裕あればで構いませんので、みていただけたら幸いです。。
m2l

2021/05/31 22:59

こちら、下記の修正処理が似たようなものが二箇所ありますのでそこが抜けてる可能性がございますね。 ---template部変更前 <img class="profile-inner-l-img" :src="uploadedImage == '' ? preview : uploadedImage.fileUrl" alt="プロフィール画像" /> ---template部変更後 <img class="profile-inner-l-img" :src="preview == '' ? uploadedImage.fileUrl : preview" alt="プロフィール画像" />
TMTN

2021/05/31 23:04

2箇所とも変更はさせていただいたのですが・・現状まだ変わらずです。。 文章では説明分かりにくいと思いましたので追記5に画像選択前と選択後、更新ボタン押下後の画像を追加しました。
m2l

2021/05/31 23:08

ありがとうございます。 これから仕事なので、また終わり次第にはなってしまいますが、返信いたしますね!
TMTN

2021/05/31 23:13

本当に本当に申し訳ございません・・・。 お時間に余裕がある時で構いませんので、ご確認いただけると幸いです。 本当にありがとうございます。。
TMTN

2021/05/31 23:20

m2l 様 本当にお恥ずかしい話なのですが、原因が判明しました・・ this.preview = ""の追加位置が.catch()の外側に追加してしまっておりました。 その為、追記5のような挙動となっていたようです。 catch()内に追加することで改善致しました・・ 早くに気づいてからご連絡すべきでした。申し訳ございません・・
m2l

2021/05/31 23:25

いえいえ! きちんと見ておらず申し訳ございません。解決できて何よりです!
TMTN

2021/05/31 23:30

とんでもございません! 私が気付く前に連絡してしまった為にご迷惑おかけしました。 本当に解決までお時間いただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問