显示Firestore V9的数据

发布于 2025-02-09 11:23:43 字数 1236 浏览 1 评论 0原文

我认为这对大多数人来说都是一个简单的问题,但是我需要帮助才能从我的服务中

  async letzteKontakteAbrufen(userid: string) {
const docref = await getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
docref.forEach(async (docu) => {
  const docid = docu.data().id;
  console.log('DOKUMENTID: ', docid);

  const docRef = doc(this.afStore, 'Chat', docid);
  await getDoc(docRef);
});

获取

数据 从“聊天”收集到收集的文档 component.ts:

this.meineKontakte = this.chatService.letzteKontakteAbrufen(userid);

想要以角度表达式显示:

  <ion-list *ngFor="let kontakt of meineKontakte | async" (click)="waehleNutzer(kontakt.data().id)">

<ion-item>
  <ion-icon name="person-circle-outline"></ion-icon>&nbsp;

  <div *ngIf="kontakt.nicknameeins !== meinNickname">
    {{ kontakt.nicknameeins }}
  </div>

  <div *ngIf="kontakt.nicknamezwei !== meinNickname">
    {{ kontakt.nicknamezwei }}
  </div>
  &nbsp;
  <div id="rechtsunten">
    <ion-label>{{kontakt.zeit?.toMillis() | date:'dd.MM.yy HH:mm'}}</ion-label>
  </div>
</ion-item>

但是我的HTML页面上没有数据,但是我敢肯定,“等待getDoc(docref).data()正在工作。 希望有人可以帮忙。

I think it's a simple question for the most of you, but I need help to get data from my service.ts to component.ts and display it on my HTML..

This is my code in service.ts

  async letzteKontakteAbrufen(userid: string) {
const docref = await getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
docref.forEach(async (docu) => {
  const docid = docu.data().id;
  console.log('DOKUMENTID: ', docid);

  const docRef = doc(this.afStore, 'Chat', docid);
  await getDoc(docRef);
});

}

Now I'd like to get the documents from "Chat"-Collection to
Component.ts:

this.meineKontakte = this.chatService.letzteKontakteAbrufen(userid);

And want to display it in Angular expressions:

  <ion-list *ngFor="let kontakt of meineKontakte | async" (click)="waehleNutzer(kontakt.data().id)">

<ion-item>
  <ion-icon name="person-circle-outline"></ion-icon> 

  <div *ngIf="kontakt.nicknameeins !== meinNickname">
    {{ kontakt.nicknameeins }}
  </div>

  <div *ngIf="kontakt.nicknamezwei !== meinNickname">
    {{ kontakt.nicknamezwei }}
  </div>
   
  <div id="rechtsunten">
    <ion-label>{{kontakt.zeit?.toMillis() | date:'dd.MM.yy HH:mm'}}</ion-label>
  </div>
</ion-item>

But there is no data on my HTML page, but I'm sure that "await getDoc(docRef).data() is working.
Hope someone can help..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怂人 2025-02-16 11:23:43

我从来没有使用过异步管(在NGFOR中)做出承诺,只有可观察到。因此,这是一个有趣的发现和探索的乐趣。

在测试时,在类似情况下,当我包装(在您的情况下,在您的情况下&lt; ion-list&gt;&lt;/ion-lt;/ion-list&gt; tag tag时,我都设法显示数据。 ng-container *ngif =“ meinekontakte | async作为联系人”&gt;

一个没有呈现数据的原因之一是,当视图首次呈现时,meinekontakte的承诺的结果是未定义的。 会防止NGFOR循环在未定义的值上。

*ngif防止渲染器崩溃,

<ng-container *ngIf="meineKontakte | async as kontakter"> <!-- added the results of the promise to a new variable called kontakter  -->
  <ion-list *ngFor="let kontakt of kontakter"> <!--  loop on kontakter instead of meineKontakte  -->
     ...
  </ion-list>
</ng-container>

因为这 在您的DOM上添加额外的元素,

您的数据不显示您的DOM 。能够准确理解您的letztekontakteabrufen函数的功能,但请确保它能返回承诺:

    async letzteKontakteAbrufen(userid: string) {
      const docref = await getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
      ...
      return docref
   }

或者也许是这样的东西:

    letzteKontakteAbrufen(userid: string) {
      return getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
   }

另一种解决方案
解决这个问题的另一种方法是将诺言的结果存储在Meinkontakte而不是承诺本身中(这是我通常这样做的方式)。

 async yourFunctionName(userId:string):Promise<void> {
    try {
       this.meineKontakte = await this.chatService.letzteKontakteAbrufen(userid: string)
     } catch(error) {
       console.error(error);
     }
  }

然后卸下HTML中的异步管。您仍然需要更改letztekontakteabrufen功能才能返回等待的数据。并确保您的ngoninit或构造函数调用您的funcunctionName函数;

我希望这可以帮助您找到最终的解决方案。

编辑
作为旁注,请在中始终将代码包裹在函数中,请{...} catch(error){console.error(error)} block当您处理承诺时。这有助于您检测和处理错误:)

编辑2-将承诺转换为可观察的

有不同的方法来创建和使用可观察到的方法。我喜欢这样做的一种相对简单,简单的方法是使用可观察到的行为。

在您的服务文件中,首先创建一个新变量以保存可观察到的变量并更改您的letztekontakteabrufen,以更新可观察到的可观察到的可观察到的可观察到的可观察到的变量,而不是返回数据:

$contacts = new BehaviorSubject<Array<any>>([])
// you should crate an interface to pass instead of using any, it would make it easier for you, but I don't know how your data looks like so I used any;

async letzteKontakteAbrufen(userid: string) {
      const docref = await getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
      ... // if you need to change your data for something do it here (reordering, retrieving extra information etc...)
      this.$contacts.next(docref) //inside the next function, add the data you want to show on your page
   }

然后在您的component.ts文件中您需要将reffference存储到可观察到的变量和变量和要触发ngoninit中的letztekonbteabrufen函数

...
$contacts = this.chatService.$contacts;

ngOnInit():void {
   this.chatService.letzteKontakteAbrufen(this.userId)
}
...

,在您的html文件中触发了:

<ion-list *ngFor="let kontakt of $contacts | async">
   ...
</ion-list>

接口上的示例:
将接口写在sepperate文件中,例如,在您的服务文件中,称为contacts.interface.ts或类的外部。然后用接口的名称替换任何关键字:

export interface Kontakt {
  userid: string;
  imageUrl?: string; // the question marks makes the property optional
  firstname: string;
  lastname:string;
  email:string
  // ... etc
}

然后将观察者更改为

$contacts = new BehaviourSubject<Array<Kontakt>>([])

如果您在letztekontaktakteabrufen中检索到的数据不是一个数组,则需要删除数组关键字,并且仅使用kontakt关键字(但是NGFOR都可以使用ngfor will will will will will will will will will )。

I have never used the async pipe (in ngFor) for promises, only observables. So this was a litle fun to discover and explore.

While testing, in a similar situation I manged to to display the data when i wrapped the (in your situation <ion-list></ion-list> tag in a <ng-container *ngIf="meineKontakte | async as contacts">

One of the reasons the data didn't get rendered without this is beacause the result of the Promise of the meineKontakte was undefined when the view first rendered. The *ngIf prevents the renderer to crash because this prevents the ngfor to loop over the undefined value.

For you this would look like:

<ng-container *ngIf="meineKontakte | async as kontakter"> <!-- added the results of the promise to a new variable called kontakter  -->
  <ion-list *ngFor="let kontakt of kontakter"> <!--  loop on kontakter instead of meineKontakte  -->
     ...
  </ion-list>
</ng-container>

The <ng-container> tag is just a placeholder that you can insert logic into without adding extra elements to your DOM.

Another reason your data doesnt show is because in your service.ts file, your letzteKontakteAbrufen function doesn't actually return anything to your component. You should make sure it returns the Promise. I wasn't able to understand exactly what your letzteKontakteAbrufen function does, but make sure it returns a Promise:

    async letzteKontakteAbrufen(userid: string) {
      const docref = await getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
      ...
      return docref
   }

or maybe something like this:

    letzteKontakteAbrufen(userid: string) {
      return getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
   }

Another solution
Another way to solve this, is to store the results of the promise in meinKontakte instead of the promise itself (this is the way I usually do it).

 async yourFunctionName(userId:string):Promise<void> {
    try {
       this.meineKontakte = await this.chatService.letzteKontakteAbrufen(userid: string)
     } catch(error) {
       console.error(error);
     }
  }

and then remove the async pipe in your html. You still need to change your letzteKontakteAbrufen function to return the await'ed data. And make sure your call the yourFunctionName function from ngOnInit or the constructor;

I hope this helps you in finding your final solution.

Edit
As a sidenote, always wrap your code in your functions in a try{...} catch(error) {console.error(error)} block when you deal with Promises. This helps you to detect and handle errors :)

Edit 2 - converting promise to an observable

There are different methods to creating and using observables. One relatively easy and simple way I like to do it is using the BehaviourSubject observable.

In your service file, first create a new variable to hold the observable and change your letzteKontakteAbrufen to update that observable with the data instead of returning data:

$contacts = new BehaviorSubject<Array<any>>([])
// you should crate an interface to pass instead of using any, it would make it easier for you, but I don't know how your data looks like so I used any;

async letzteKontakteAbrufen(userid: string) {
      const docref = await getDocs(collection(this.afStore, 'Nutzer', userid, 'chats'));
      ... // if you need to change your data for something do it here (reordering, retrieving extra information etc...)
      this.$contacts.next(docref) //inside the next function, add the data you want to show on your page
   }

then inside your component.ts file you need to store a refference to the observable into a variable and to trigger the letzteKontakteAbrufen function in ngOnInit

...
$contacts = this.chatService.$contacts;

ngOnInit():void {
   this.chatService.letzteKontakteAbrufen(this.userId)
}
...

And the in your html file:

<ion-list *ngFor="let kontakt of $contacts | async">
   ...
</ion-list>

Example on an interface:
Write the interface in a sepperate file, for example called contacts.interface.ts or outside of the class in your service file. And then replace the any keyword with the name of the interface:

export interface Kontakt {
  userid: string;
  imageUrl?: string; // the question marks makes the property optional
  firstname: string;
  lastname:string;
  email:string
  // ... etc
}

and then change your Observable to

$contacts = new BehaviourSubject<Array<Kontakt>>([])

if your data retrieved in your letzteKontakteAbrufen is not an array you need to remove the Array keyword and only use Kontakt keyword (but then the ngfor wouldt work either).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文