【发布时间】:2023-03-09 04:03:02
【问题描述】:
我正在使用Firebase Realtime DB 开发一个Ionic 条形码扫描仪应用程序。
在启动时,应用程序应该从Firebase 同步数据。但不知何故,该应用程序似乎在初始化/与数据库同步完成之前开始工作。因此用户不会看到任何数据。
在几次重启后,应用完成了数据同步,用户终于可以看到数据了。 请指导我解决此问题。每次用户使用该应用时,该应用都会同步数据?
提前致谢!
tabs.page.ts
import { Component, OnInit } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { DataServiceService } from '../../app/data-service.service';
import { Toast } from '@ionic-native/toast/ngx';
import { Platform, AlertController } from '@ionic/angular';
import * as moment from 'moment';
@Component({
selector: 'app-tabs',
templateUrl: './tabs.page.html',
styleUrls: ['./tabs.page.scss'],
})
export class TabsPage implements OnInit {
productViews: any = {};
productViewsbyUser: any[] = [];
isProdcutsAvailable = true;
selectedProduct: any;
isCameraOpen = false;
showScan = false;
products: any[] = [];
productFound = true;
displayUserName: any;
exitModalDisplayed = false;
constructor(
private barcodeScanner: BarcodeScanner,
private toast: Toast,
public platform: Platform,
public dataService: DataServiceService,
public alertCtrl: AlertController) {
console.log(`Tabs Page called`);
}
ngOnInit() {
this.productHunt();
}
productHunt() {
this.dataService.getProducts()
.subscribe((response) => {
this.products = <any[]><unknown>response;
console.table('products ', this.products);
});
}
getMoment() {
return moment().milliseconds(0);
}
// Start scanning procedure
scan() {
this.selectedProduct = {};
this.isCameraOpen = true;
this.showScan = true;
this.barcodeScanner.scan().then((barcodeData) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 500);
if (barcodeData.cancelled) {
return;
}
console.log(`barcodeData`, barcodeData);
this.selectedProduct = this.products.find(product => product.prodId === barcodeData.text);
if (this.selectedProduct !== undefined) {
this.selectedProduct.scannedAt = this.getMoment().toISOString();
// this.selectedProduct.userName = this.displayUserName(); // TO TEST !!!
this.productFound = true;
// insert product views with firebase generated based key
this.dataService.insertProductViewAnalytics(this.selectedProduct)
.subscribe(() => {
console.log(`Product view analytics inserted in Firebase`);
this.initScanHistoryData();
});
} else {
this.productFound = false;
this.toast.show(`Product not found`, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
}
}, (err) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 1000);
this.toast.show(err, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
});
}
async initScanHistoryData() {
this.dataService.getProductViewsForUser()
.subscribe((response) => {
this.productViews = response;
const userProductViews = [];
// tslint:disable-next-line: forin
for (const key in this.productViews) {
userProductViews.push(this.productViews[key]);
}
userProductViews.sort(function (a, b) {
return moment(b.scannedAt).diff(moment(a.scannedAt));
// ENTER USER NAME HERE???
});
this.productViewsbyUser = userProductViews;
console.log('user productViews ', userProductViews);
if (this.productViewsbyUser.length) {
this.isProdcutsAvailable = true;
} else {
this.isProdcutsAvailable = false;
}
console.log('productViews ', this.productViews);
});
}
}
data-service.service.ts
import { Component, OnInit } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { DataServiceService } from '../../app/data-service.service';
import { Toast } from '@ionic-native/toast/ngx';
import { Platform, AlertController } from '@ionic/angular';
import * as moment from 'moment';
@Component({
selector: 'app-tabs',
templateUrl: './tabs.page.html',
styleUrls: ['./tabs.page.scss'],
})
export class TabsPage implements OnInit {
productViews: any = {};
productViewsbyUser: any[] = [];
isProdcutsAvailable = true;
selectedProduct: any;
isCameraOpen = false;
showScan = false;
products: any[] = [];
productFound = true;
displayUserName: any;
exitModalDisplayed = false;
constructor(
private barcodeScanner: BarcodeScanner,
private toast: Toast,
public platform: Platform,
public dataService: DataServiceService,
public alertCtrl: AlertController) {
console.log(`Tabs Page called`);
}
ngOnInit() {
this.productHunt();
}
productHunt() {
this.dataService.getProducts()
.subscribe((response) => {
this.products = <any[]><unknown>response;
console.table('products ', this.products);
});
}
getMoment() {
return moment().milliseconds(0);
}
// Start scanning procedure
scan() {
this.selectedProduct = {};
this.isCameraOpen = true;
this.showScan = true;
this.barcodeScanner.scan().then((barcodeData) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 500);
if (barcodeData.cancelled) {
return;
}
console.log(`barcodeData`, barcodeData);
this.selectedProduct = this.products.find(product => product.prodId === barcodeData.text);
if (this.selectedProduct !== undefined) {
this.selectedProduct.scannedAt = this.getMoment().toISOString();
// this.selectedProduct.userName = this.displayUserName(); // TO TEST !!!
this.productFound = true;
// insert product views with firebase generated based key
this.dataService.insertProductViewAnalytics(this.selectedProduct)
.subscribe(() => {
console.log(`Product view analytics inserted in Firebase`);
this.initScanHistoryData();
});
} else {
this.productFound = false;
this.toast.show(`Product not found`, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
}
}, (err) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 1000);
this.toast.show(err, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
});
}
async initScanHistoryData() {
this.dataService.getProductViewsForUser()
.subscribe((response) => {
this.productViews = response;
const userProductViews = [];
// tslint:disable-next-line: forin
for (const key in this.productViews) {
userProductViews.push(this.productViews[key]);
}
userProductViews.sort(function (a, b) {
return moment(b.scannedAt).diff(moment(a.scannedAt));
// ENTER USER NAME HERE???
});
this.productViewsbyUser = userProductViews;
console.log('user productViews ', userProductViews);
if (this.productViewsbyUser.length) {
this.isProdcutsAvailable = true;
} else {
this.isProdcutsAvailable = false;
}
console.log('productViews ', this.productViews);
});
}
}
【问题讨论】:
-
作为 UI 注释,您希望某些内容显示在屏幕上,即使它不是数据,因为仍在获取数据、微调器、进度条等。并且选项卡正在加载,然后要求数据,所以总会有延迟。如果您只显示几秒钟的空白屏幕,研究表明用户会很快放弃您的应用。
-
您好,感谢您的评论。我明白你的意思了。但问题是,该应用程序将开始运行,并且尚未获取一些数据,并且不幸的是之后也不会同步。只有在应用程序重新启动几次后,整个数据才被加载。
-
标签页是起始页吗?您可以将对服务的调用移动到 app.component 中,这样它就可以更早地开始。数据的获取会受到随机因素的影响,所以你永远不能假设它总是以一定的速度加载。之后的同步听起来是一个不同的(也是更重要的)问题。
-
嗨史蒂夫,再次感谢您的回答。我试图在 app.componet 文件中调用该服务,但不幸的是它不起作用。登录后,产品数据似乎以某种方式未同步。与其他数据相同,例如个人资料数据等。
-
您可以使用角度生命周期事件和离子页面生命周期事件,例如
ngAfterViewInits和ionViewDidEnter。
标签: javascript angular firebase ionic-framework firebase-realtime-database