我对 firestore 和 angular 完全陌生,但经过几天的工作,我设法编写了一个 ionic/angular web 应用程序,它使用 google firestore 作为后端。
每次在 Firestore 中添加/删除/更新条目时,该应用程序都会显示实时更新。
我通过订阅 valueChanges 对数据库中的变化使用react:
itemSubscription;
private itemsCollection: AngularFirestoreCollection<Item>;
items: Observable<Item[]>;
constructor(private afs: AngularFirestore) {
this.itemsCollection = afs.collection<Item>('zones/Zone1/trashdumps');
this.items = this.itemsCollection.valueChanges();
// subscribe() is used to get a stream of updates.
this.itemSubscription = this.items.subscribe(
//function invoked on every new collection snapshot
(docs) => {
docs.forEach( doc => {
console.log('Current data:', doc);
})
},
//function invoked on error
(msg) => { console.log('Error Getting Location: ', msg); }
);
我的数据库的典型条目是这样的
{
"bags":
{
"integerValue": "2"
},
"location":
{
"geoPointValue":
{
"latitude": 52.3696,
"longitude": 4.86561111
}
}
}
当我通过 google firestore Web 控制台手动将条目添加到 firestore 时,我的应用会收到正确的更新。
当我通过 Rest API 向 firestore 添加条目时,我的应用会收到正确的更新。
当我使用 python 的 firestore-admin 模块向 firestore 添加条目时,我的应用程序收到一个空更新。注意:只有在创建条目时收到的实时更新是空的!如果我只是重新加载我的应用程序并再次查询数据库,我会得到一个正确的条目!从各个角度来看,python 编写的 db 条目都是正确的。
这是我对“正确更新”的意思(取自 chrome 控制台):
tab2.page.ts:50 Current data: Object
bags: 2
location: GeoPoint {_lat: 52.3696, _long: 4.86561111}
__proto__: Object
这是“emtpy”,错误的更新:
tab2.page.ts:50 Current data: Object
__proto__: Object
我已经尝试订阅 snapshotChanges() 而不是 valueChanges()。元数据确实存在,但没有 .data() 方法来获取字段。空也。
这就是我在 Python 中向 firestore 添加条目的方式(简化版):
class MyPoint(object):
def __init__(self, bags, lat, long):
self.bags = bags
self.location = GeoPoint(lat, long)
@staticmethod
def from_dict(source):
# ...
pass
def to_dict(self):
# ...
return {
'bags': self.bags,
'location': self.location
}
class MyDatabase(object):
_firebaseConfig = {
[...]
}
def __init__(self):
# Use the application default credentials
cred = credentials.ApplicationDefault()
firebase_admin.initialize_app(cred, self._firebaseConfig)
self.db = firestore.client()
def send(self, point):
self.db.collection(u'mycollection').add(point.to_dict())
point = MyPoint(1,0.0,0.0)
db = MyDatabase()
db.send(point)
难道我做错了什么? firestore-admin 是否可以分两步执行条目创建,首先创建一个空记录,然后为其设置值?那会解释吗?
我希望这很清楚,感谢您的帮助,真的是新手。
更新
我更准确地记录了订阅 DocumentChangeAction Observables 时发生的事情,我更加困惑。
在以下日志中,“Doc”代表 DocumentChangeAction,而“data”代表实际的 .payload.doc.data() 文档正文。
从一个空数据库开始,这是我添加第一点时收到的更新:
tab2.page.ts:49 Current Doc: {type: "added", payload: {…}}
tab2.page.ts:50 Current data: {}
tab2.page.ts:49 Current Doc: {type: "modified", payload: {…}}
tab2.page.ts:50 Current data: {bags: 1, location: GeoPoint}
事实上,一个空的“添加”和一个随后的“修改”。我可以处理这个。
但这就是我添加第二点(“bags = 8”之一)时得到的结果:
tab2.page.ts:49 Current Doc: {type: "modified", payload: {…}}
tab2.page.ts:50 Current data: {bags: 1, location: GeoPoint}
tab2.page.ts:49 Current Doc: {type: "added", payload: {…}}
tab2.page.ts:50 Current data: {}
tab2.page.ts:49 Current Doc: {type: "modified", payload: {…}}
tab2.page.ts:50 Current data: {bags: 1, location: GeoPoint}
tab2.page.ts:49 Current Doc: {type: "modified", payload: {…}}
tab2.page.ts:50 Current data: {bags: 8, location: GeoPoint}
这太多了:4 次更新。
只是我还是这真的不必要的复杂?
最佳答案
我测试了同样的结果,valueChanges将返回每次更改的所有对象的列表。您应该寻找像 stateChanged 这样的替代方案只为您提供最新的更改。
this.items = db.collection('mytesting').valueChanges();
this.items.subscribe(
//function invoked on every new collection snapshot
(docs) => {
docs.forEach( doc => {
console.log('Current data:', doc);
})
},
//function invoked on error
(msg) => { console.log('Error Getting Location: ', msg); }
);
打印控制台记录时的所有项目:
app.component.ts:21 Current data: {name: "nagaraj"}
app.component.ts:21 Current data: {name: "Sample"}
app.component.ts:21 Current data: {name: "Test"}
app.component.ts:21 Current data: {name: "Fetch"}
我添加一个新项目说
{name: "Another"}
,它打印app.component.ts:21 Current data: {name: "nagaraj"}
app.component.ts:21 Current data: {name: "Sample"}
app.component.ts:21 Current data: {name: "Test"}
app.component.ts:21 Current data: {name: "Fetch"}
app.component.ts:21 Current data: {name: "Another"}
如果我将行更改为:
this.items = db.collection('mytesting').stateChanges();
它不会打印所有项目,只打印状态更改为
added
的文档, modified
和 removed
.然而 ,我使用了 AngularFirestore,无需订阅
valueChanges().subscribe(
就可以在 UI 中显示相同的内容:app.component.ts :
import { Component } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
items: Observable<any[]>;
constructor(db: AngularFirestore) {
this.items = db.collection('mytesting').valueChanges();
}
}
app.component.html
<ul>
<li class="text" *ngFor="let item of items | async">
{{item.name}}
</li>
</ul>
我没有使用
subscribe
.
关于python - 仅当通过 python firebase SDK 添加文档时,才在 angularfire 上更新空文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58006524/