小编Tho*_*mas的帖子

Firestore 子集合与数组

首先,我知道 Firestore 是如何工作的,并且花了很多时间来评估不同的方法以获得良好的结构。我仍然在考虑以下情况:

有一个已知食谱的数据库。用户可以添加食谱,但必须确认它们是真实的食谱,而不仅仅是一些变体。因此,每个用户都可以从用户生成的食谱列表中选择食谱来说明他们知道如何烹饪(或添加新食谱)。

现在我希望用户与其他人分享他们的收据列表,但我不确定如何使用 Firestore 最好地实现这一点。诀窍是,我想一次显示所有食谱,而不想对它们进行分页。

我目前正在评估两种可能性:

子集

每当用户分享他的列表时,查看该列表的用户将不得不加载整个食谱列表,这可能会导致大量的文档读取(我想实际上大约为 50,在极少数情况下可能为 1000)。

优点:

  • 更自然的结构
  • 更易于维护(例如删除配方,检查特定配方是否存在)
  • 更容易添加字段(例如 timeOfCreation、comment、personalRating 等)

缺点:

  • 从长远来看,可能会导致大量读取

数组

我可以将每个已知的配方(id 和 imageURL)保存在一个数组中的用户文档(或作为单个子文档“KnownRecipes”)中。这个数组可以是

recipesKnown: [{rid: 293ndwa, imageURL: image1.com, timeAdded: 8371201332}, 
               {rid: 9012831, imageURL: image1.com, timeAdded: 8371201871},
               {rid: jd812da, imageURL: image1.com, timeAdded: 8371201118},
               ...
              ]
Run Code Online (Sandbox Code Playgroud)

优点:

  • 每当有人想查看其他用户的列表时,我只需要阅读一份文档
  • 读取用户列表可能更快

缺点:

  • 更新特定的配方很困难(例如,有人想要更改 imageURL:我需要在本地更改列表并将整个文档作为更新发送到服务器 - 因为我不能只更改数组中的单个元素)
  • 当用户决定拥有大约 1000 个食谱时(这可能永远不会发生,但可能会发生),就可能达到 Firestore 限制的 1MiB 限制。一种可能的解决方法是创建一个单独的文档并将这两个数组拆分为这两个文档。

对我来说,子集合的想法似乎是解决这个问题的更“干净”的解决方案,但也许我错过了一些关于为什么这些解决方案中的一个比另一个更好的论点。

我最常见的查询如下(按重要性降序排列):

  • 用户可以烹饪哪些食谱
  • 将用户可以烹饪的食谱添加到用户列表中
  • 谁可以烹饪特定的食谱(有一个食谱 - > 厨师子集)
  • 更新用户可以烹饪的现有食谱

firebase google-cloud-firestore

32
推荐指数
2
解决办法
4803
查看次数

查询附近的位置

我正在使用Firebase来存储用户上次扫描的纬度和经度.

条目如下所示:

"Bdhwu37Jdmd28DmenHahd221" : {
  "country_code" : "at",
  "firstname" : "John",
  "gender" : "m",
  "lat" : 11.2549387,
  "lon" : 17.3419559
}
Run Code Online (Sandbox Code Playgroud)

每当用户按下特定的"搜索"按钮时,我希望我的Firebase功能可以获取离发送请求的人最近的人.

由于Firebase只允许在一个字段后查询,因此我决定添加country_code,以便对该字段进行一些范围限制和查询.但是当我加载特定国家/地区的每个用户然后检查给定用户与同一国家/地区中所有其他用户之间的最小距离时,它仍然非常慢.

已经有5个用户,该功能需要40秒才能达到效果.

我还读过有关复合索引的内容,但我需要以某种方式结合纬度和经度并查询这两个字段.

有没有办法让这里涉及第二个和第三个查询(例如搜索相同的country_code,然后搜索类似的经度和纬度)或者我是否必须在我的服务器代码中解决这个问题?

firebase firebase-realtime-database

13
推荐指数
1
解决办法
9330
查看次数

在 Flutter 中初始化通知的正确位置

我目前正在努力让通知按照我希望的方式在 Flutter 上运行。我目前的解决方案是有一个动态的 LandingPage,它 - 取决于 FirebaseAuth - 重定向到登录或主屏幕。

MaterialApp(
   theme: ThemeData(
   ...
   home: Scaffold(body: Builder(builder: (context) => LandingPage()))
),
Run Code Online (Sandbox Code Playgroud)

在 LandingPage 中,我将在我的 Singleton 中调用一个函数来为我设置通知。如您所见,我在这里传递上下文。这是因为我想从通知的onMessage回调中显示 Snackbar 。

class LandingPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    FirebaseUser user = Provider.of<FirebaseUser>(context);
    if (user != null) {
      Singleton().setupMessaging(user.uid, context); //This is the line
      return MainPage(userId: user.uid);
    } else {
      while(Navigator.canPop(context)){
        Navigator.pop(context);
      }
      return LoginPage();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我正在努力实现,一旦用户登录,就让消息传递系统运行。如果当前令牌未定义,我只设置回调。

我现在遇到的问题是,所说的上下文不是应用程序范围的,这意味着,一旦我导航到具有自己的上下文的新 Widget,就无法再显示 Snackbar。现在我不确定这是否是初始化消息传递的正确位置,因为没有应用程序范围的上下文。

setupMessaging(String uid) async{
   if((await SharedPreferences.getInstance()).getBool('bNotifications') ?? true){
     print("bNotifications …
Run Code Online (Sandbox Code Playgroud)

push-notification google-cloud-messaging flutter

6
推荐指数
1
解决办法
3094
查看次数

在 Flutter 中保存 Google 地图状态

所以我基本上有一个带有三个选项卡的应用程序。在其中一个上,我有一个带有相应标记的 Google 地图和一个带有基于位置的 Firestore 查询的侦听器。当选择该选项卡时,将查询附近的元素并将其显示在地图上。

但是,当我更改选项卡并再次返回地图时,地图、侦听器和所有标记将再次设置(自initState()dispose()被调用以来)。

当选择页面时,保存地图中的所有状态并继续地图的先前状态的最佳方法是什么?

我读过一些有关 Redux 和 BloC 的内容,这是我在这里需要的模式吗?如果是的话,如何将其应用于 GoogleMap?

google-maps flutter

5
推荐指数
1
解决办法
1819
查看次数

关于documentId的Firestore集合组查询

在我的情况下,用户可以“喜欢”另一个用户的个人资料。结果,我为每个用户创建了一个名为“ likedBy”的子集合,在其中为特定用户创建了一个文档,例如:

users(col)-> User A(doc)-> LikeedBy(col)-> User B(doc),User C(doc)

因此,在极少数情况下删除用户,我想删除该用户的所有喜欢的问题。

我只是不确定这是否可能(一种解决方法是将userId再次保存在所述文档中并进行查询)。

我基本上正在寻找的是这样的:

db.collectionGroup('likedBy').where(firebase.firestore.FieldPath.documentId(), '==', "User A").get();
Run Code Online (Sandbox Code Playgroud)

问题是,我无法在Firestore控制台中为documentId创建索引。

javascript firebase google-cloud-firestore

4
推荐指数
2
解决办法
1626
查看次数