Ionic结合Firestore开发时详情页二次进入数据未刷新问题求助
问题原因
- 执行顺序错误:
myDefaultMethodToFetchData方法中先调用getItems,后赋值userId,导致查询时使用的是上一次的用户ID或者undefined,请求路径错误 - Firestore缓存问题:Firestore的
get()方法默认优先读取本地离线缓存,修改后的服务端数据不会主动同步到缓存,导致拿到的始终是旧数据 - Video资源不会自动重载:
source标签的src属性变更后,浏览器不会自动重新加载视频资源,即使数据更新了,页面上的视频还是之前加载的旧资源
修复方案
1. 修正执行顺序
调整myDefaultMethodToFetchData方法内的代码顺序,先给userId赋值再发起查询:
myDefaultMethodToFetchData() { console.log("IN") // 先赋值用户ID this.userId = this.authService.userData.uid; this.getItems().then((data) => { console.log("IN2222") this.items = data this.item0 = this.items[0]; this.item1 = this.items[1]; // 数据更新后手动重载视频 this.reloadVideos(); }) }
2. 强制Firestore从服务端拉取最新数据
给get()方法添加参数{ source: 'server' },跳过本地缓存直接请求服务端最新数据:
getItems() { const itemsRef = firebase.firestore().collection("user_orders/" + this.userId+"/reservations") .where("ordini", "<", 10).limit(5); // 强制从服务端获取数据 return itemsRef.get({ source: 'server' }) .then((querySnapshot) => { return querySnapshot.docs.map(doc => doc.data()); }) .catch((error) => { console.log("Error getting documents: ", error); }); }
3. 手动重载视频资源
组件代码修改
导入ViewChild和ElementRef,获取video元素的DOM引用,添加重载方法:
import { ViewChild, ElementRef } from '@angular/core'; export class DetailPage implements OnInit, ViewWillEnter { @ViewChild('video1') video1: ElementRef<HTMLVideoElement>; @ViewChild('video2') video2: ElementRef<HTMLVideoElement>; // 原有变量保持不变 // 原有方法保持不变,新增重载方法 reloadVideos() { if (this.video1?.nativeElement) { this.video1.nativeElement.load(); } if (this.video2?.nativeElement) { this.video2.nativeElement.load(); } } }
HTML代码修改
给video标签添加模板引用变量:
<video #video1 id="video1" height="320" width="240" controls> <source src="{{item0?.downloadURL}}" type="video/mp4"> <source src="{{item0?.downloadURL}}" type="video/ogg"> </video> <video #video2 id="video2" height="320" width="240" controls> <source src="{{item1?.downloadURL}}" type="video/mp4"> <source src="{{item1?.downloadURL}}" type="video/ogg"> </video>
可选优化方案
你也可以改用Firestore的实时快照监听onSnapshot替代单次get请求,服务端数据发生变更时会自动推送到前端,无需每次进入页面手动拉取:
getItemsRealtime() { const itemsRef = firebase.firestore().collection("user_orders/" + this.userId+"/reservations") .where("ordini", "<", 10).limit(5); itemsRef.onSnapshot((querySnapshot) => { this.items = querySnapshot.docs.map(doc => doc.data()); this.item0 = this.items[0]; this.item1 = this.items[1]; this.reloadVideos(); }) }
内容的提问来源于stack exchange,提问作者sirss
相关产品推荐
相关产品推荐

