Saturday, 28 September 2019

Empty document updates on angularfire only when doc is added through python firebase SDK

I'm absolutely new to firestore and angular, but after some days of work I have managed to write an ionic/angular web app, that uses google firestore as a back-end.

The app simply shows real-time updates everytime an entry is added/removed/updated in firestore.

I'm reacting to changes in the db by subscribing to valueChanges:

  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); }
    );

The typical entry of my db is something like this

{
    "bags": 
    {
        "integerValue": "2"
    },
    "location": 
    {
      "geoPointValue": 
      {
        "latitude": 52.3696,
        "longitude": 4.86561111
      }
    }
  }

When I add entries to firestore manually through google firestore web console, my app receives correct updates.

When I add entries to firestore through the Rest API, my app receives correct updates.

When I add entries to firestore using python's firestore-admin module, my app receives an empty update. NOTICE: only the real-time update received at entry creation is empty! If I just reload my app and query the db again, I get a correct entry! The db entry written by python is correct from every point of view.

Here is what I mean for "correct update" (taken from chrome console):

tab2.page.ts:50 Current data: Object
                              bags: 2
                              location: GeoPoint {_lat: 52.3696, _long: 4.86561111}
                              __proto__: Object

This is instead the "emtpy", wrong update:

tab2.page.ts:50 Current data: Object
                              __proto__: Object

I have already tried to subscribe to snapshotChanges() instead of valueChanges(). The metadata are indeed present, but there is no .data() method to get the fields. Empty as well.

This is how I add entries to firestore in Python (simplified):


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)

Am I doing something wrong? Is it possible that firestore-admin performs entry creation in two steps, first creating an empty record and then settings value for it? That would explain it?

I hope this is clear, thanks for any help, really a newbie with this.

Update

I've logged more accurately what happens when I subscribe to DocumentChangeAction Observables and I'm even more confused.

In the following log, "Doc" represents the DocumentChangeAction, while "data" represents the actual .payload.doc.data() document body.

Starting from an empty db, this is the updates I receive when I add the first point:

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}

Indeed, an empty "add" and a subsequent "modify". I could deal with this.

But this is what I get when I add the second point (the "bags=8" one):

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}

This is too much: 4 updates.

  1. The previous entry is modified for some reason. Metadata maybe, not the fields
  2. The empty add is performed
  3. The previous entry is sent again (?)
  4. Finally the update for the new entry is sent, with data

Is it just me or is this really unnecessarily complicated?



from Empty document updates on angularfire only when doc is added through python firebase SDK

No comments:

Post a Comment