关于documentId

时间:2019-05-15 12:41:23

标签: javascript firebase google-cloud-firestore

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

  

用户(col)->用户A(doc)-> LikedBy(col)->用户B(doc),用户C(doc)

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

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

我基本上想要的是这样的东西:

db.collectionGroup('likedBy').where(firebase.firestore.FieldPath.documentId(), '==', "User A").get();

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

3 个答案:

答案 0 :(得分:8)

更新2019-12-02:Firebase支持伸出援手,问我是否仍然希望解决此问题。咄。 更新2019-09-27:Firebase支持已确认这是一个错误。没有消息何时将被修复。实际上,documentId()应该应该能够直接用于 文档ID。

documentID 可以用作查询的一部分,但是,正如上面@ greg-ennis所述,它需要偶数个段。事实证明,如果您确实需要一个collectionGroup(我需要),那么要比较的“ Id”需要冗余添加该collectionGroup ID /名称作为分段:

db.collectionGroup('likedBy')
.where(firebase.firestore.FieldPath.documentId(), '==', "likedBy" + "/" + "User A")
.get();

我用过它并且它(* sorta)可以工作。 (诚​​然,我花了2个小时才弄清楚了,上面的问题帮助我们集中了搜索范围)

另一方面,您要使用collectionGroup的 not 特定情况是 not 。记住什么集合组-一种引用一组单独集合的方法,就好像它们是一个一样。在这种情况下,持有“用户A”喜欢的“集合”作为“用户A”文档下的集合存在。只需删除 that 单个集合,然后再删除“用户A”的文档。无需引入其他人的喜欢。

Sorta:比较的字段路径显然必须是文档的 complete 路径。如果您知道documentId,但是对于“原因”,您将不知道子集合是哪个文档的完整路径包括(请确定使用的原因)首先是collectionGroup方法),这似乎有点死胡同了。继续努力。

已验证且已提交错误报告:FieldPath.documentID()不会与documentId进行比较;它将与完全分段的文档路径进行比较,与您必须提供给.doc(path)的完全相同:

智慧:在“ TopCollection / document_this / NextCollection / document_that / Travesty / document_Id_I_want”中找到文档

使用collectionGroup“ Travesty”

db.collectionGroup("Travesty")
.where(firebase.firestore.FieldPath.documentId(), '==', "document_id_I_want")

... 将会失败,但是...

db.collectionGroup("Travesty")
.where(firebase.firestore.FieldPath.documentId(), '==', "TopCollection/document_this/NextCollection/document_that/Travesty/document_Id_I_want")
.get()

... 成功。这使它无用,因为如果我们拥有所有那个信息,我们将只使用:

db.doc("TopCollection/document_this/NextCollection/document_that/Travesty/document_Id_I_want")
.get()

答案 1 :(得分:2)

您无法使用以下查询:

import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';

import './styles.css';

const DemoComponent = () => {
  useEffect(() => {
    return () => {
      console.log('******************* UNMOUNTED');
    };
  }, []);
  return <div>Demo Component</div>;
};

const HomeComponent = () => {
  return <div>Home Component</div>;
};

function App() {
  return (
    <BrowserRouter>
      <div>
        <Link to="/">To Home</Link>
        <br />
        <Link to="/aaa">To AAA</Link>
        <br />
        <Link to="/bbb">To BBB</Link>
      </div>
      <Switch>
        <Route path="/(aaa|bbb)" component={DemoComponent} />
        <Route path="/" component={HomeComponent} />
      </Switch>
    </BrowserRouter>
  );
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);  

这是因为收集组查询仅对文档属性有效,而对文档ID则无效。根据有关collection group queries的官方文档:

db.collectionGroup('likedBy').where(firebase.firestore.FieldPath.documentId(), '==', "User A").get();

您查询db.collectionGroup('landmarks').where('type', '==', 'museum'); 子集合,其中landmarks属性保存着type的值。

一种解决方法是将用户ID存储在数组中并使用museum,但请记住,对于您使用的每个集合组查询,您都需要一个索引,但不幸的是,您无法以编程方式创建该索引。即使您可以在Firebase控制台中创建索引,也无法为您提供帮助,因为您可以动态获取这些ID。因此,不能为每个用户分别创建索引,因为您很快就会到达maximim number of indexes

  

数据库的最大组合索引数:200

要解决此类问题,您应该考虑在每个用户对象下添加一个数组,并使用如下查询:

array-contains

usersRef.where("usersWhoLikedMe", "array-contains", "someUserId") 是array类型的属性。

答案 2 :(得分:0)

如果将用户A和B的ID添加到文档本身:

users(col) -> User A(doc) -> likedBy(col) -> User B ({user_id: B, profile_liked_id: A})

然后您可以使用以下查询:

db.collectionGroup('likedBy').where('user_id', '==', 'B');