Странное количество событий в случае добавления элемента, включающего поля serverTimestamp, в коллекцию firestore - PullRequest
0 голосов
/ 30 января 2019

Я пишу веб-приложение, позволяющее пользователям обмениваться сообщениями по определенной теме.Я использую FireBase в качестве бэкэнда, данные хранятся в Firestore.Сохраненное сообщение представляет собой довольно простой объект, он приблизительно содержит идентификатор, содержимое и две серверные метки времени как время создания и последнего обновления.Я слушаю изменения, используя метод valueChange ().Каждый раз, когда я добавляю новый объект сообщения в хранилище с помощью метода set (), я получаю два обновления вместо ожидаемого.Это нормальное поведение?Считается ли создание serverTimestamp обновлением данных, и по этой причине я получаю два события?

Ниже моего кода.Функция getData () запускается нажатием кнопки на веб-странице.

  @Component({
  selector: 'app-access',
  templateUrl: './access.component.html',
  styleUrls: ['./access.component.scss']
})
export class AccessComponent implements OnInit {

  m: Message;
  subscription: Subscription;

  constructor(
    private _db: AngularFirestore, 
    private _auth: AuthService) { }

  ngOnInit(): void {
    console.log('START...');
    this.subscription = this._db.collection<any>(MESSAGES_ENDPOINT).valueChanges()
      .subscribe((response) => {
        console.log('data received: ', response);
      });

  }

  getData(): void {
    this.m = {
      id: this._db.createId(),
      title: ' Just a test',
      message: 'MESSAGE ' + new Date().getSeconds(),
      type: 1,
      topic: '999999',
      state: 0,
      from: this._auth.getUserID(),
      fromAvatar: this._auth.getAvatar(),
      fromDisplayName: this._auth.getDisplayName(),
      to: 'JOE COOL',
      created: firebase.firestore.FieldValue.serverTimestamp(),
      lastUpdate: firebase.firestore.FieldValue.serverTimestamp()
    };

    this._db.collection<Message>(MESSAGES_ENDPOINT).doc(this.m.id).set(this.m)
    .then(() => console.log('Document successfully stored'))
    .catch((error) => console.error('Error writing document: ', error));
  }
}

В результате я получаю следующий вывод:

START...
access.component.ts:30 data received:  
(2) [{…}, {…}]  <== **after subscription, returns data already stored in database **


access.component.ts:30 data received:  <== ** after submission of new entry, surprisingly **the timestamp fields are null** 
(3) [{…}, {…}, {…}]
0: {created: Timestamp, from: "R1qkoc1LPefeNTO1fdSKnBJbHE92", fromAvatar: "/assets/images/avatars/avatar_placeholder.png", fromDisplayName: "Guest", id: "Da7Bpaw2Y4ZzSqa44eqb", …}
1: **{created: null**, from: "R1qkoc1LPefeNTO1fdSKnBJbHE92", fromAvatar: "/assets/images/avatars/avatar_placeholder.png", fromDisplayName: "Guest", id: "HeY4dqqhwVEUgNIpczCo", …}
2: {created: Timestamp, from: "R1qkoc1LPefeNTO1fdSKnBJbHE92", fromAvatar: "/assets/images/avatars/avatar_placeholder.png", fromDisplayName: "Guest", id: "RyDq5pwW0DvnErXH6J2M", …}
length: 3
__proto__: Array(0)

access.component.ts:30 data received:  <== ** Second update, this time with correct timestamp fields
(3) [{…}, {…}, {…}]
0: {created: Timestamp, from: "R1qkoc1LPefeNTO1fdSKnBJbHE92", fromAvatar: "/assets/images/avatars/avatar_placeholder.png", fromDisplayName: "Guest", id: "Da7Bpaw2Y4ZzSqa44eqb", …}
1: {**created: Timestamp**, from: "R1qkoc1LPefeNTO1fdSKnBJbHE92", fromAvatar: "/assets/images/avatars/avatar_placeholder.png", fromDisplayName: "Guest", id: "HeY4dqqhwVEUgNIpczCo", …}
2: {created: Timestamp, from: "R1qkoc1LPefeNTO1fdSKnBJbHE92", fromAvatar: "/assets/images/avatars/avatar_placeholder.png", fromDisplayName: "Guest", id: "RyDq5pwW0DvnErXH6J2M", …}
length: 3
__proto__: Array(0)

1 Ответ

0 голосов
/ 30 января 2019

Это нормальное поведение.SDK угадывает значение метки времени для любых локальных слушателей, которые сработают, когда какой-либо из его документов по какой-либо причине изменится.Затем, когда фактическое значение будет известно с сервера, слушатель будет снова запущен с новым значением.

Если вы не хотите локальных обновлений и только тех, которые поступают с сервера, вам придетсяукажите для запроса, что вас интересуют только снимки документов, поступающие непосредственно с сервера.Я не знаю, как AngularFire это раскрывает, но в чистой версии SDK для JavaScript вы смотрите на атрибут hasPendingWrites SnapshotMetadata.Вы можете получить метаданные моментального снимка, указав, что хотите [получать изменения метаданных в запросе] [2].

...