在 PHP、Firebase 中获取集合中的所有文档

时间:2021-01-30 00:32:11

标签: php firebase google-cloud-firestore

在 Cloud Firestore 文档中: https://firebase.google.com/docs/firestore/query-data/get-data

我复制了这个例子:

$citiesRef = $db->collection('cities');
$citiesRef->document('SF')->set([
    'name' => 'San Francisco',
    'state' => 'CA',
    'country' => 'USA',
    'capital' => false,
    'population' => 860000
]);
$citiesRef->document('LA')->set([
    'name' => 'Los Angeles',
    'state' => 'CA',
    'country' => 'USA',
    'capital' => false,
    'population' => 3900000
]);
$citiesRef->document('DC')->set([
    'name' => 'Washington D.C.',
    'state' => null,
    'country' => 'USA',
    'capital' => true,
    'population' => 680000
]);
$citiesRef->document('TOK')->set([
    'name' => 'Tokyo',
    'state' => null,
    'country' => 'Japan',
    'capital' => true,
    'population' => 9000000
]);
$citiesRef->document('BJ')->set([
    'name' => 'Beijing',
    'state' => null,
    'country' => 'China',
    'capital' => true,
    'population' => 21500000
]);
printf('Added example cities data to the cities collection.' . PHP_EOL);

和请求:

$citiesRef = $db->collection('cities');
$query = $citiesRef->where('capital', '=', true);
$documents = $query->documents();
foreach ($documents as $document) {
    if ($document->exists()) {
        printf('Document data for document %s:' . PHP_EOL, $document->id());
        print_r($document->data());
        printf(PHP_EOL);
    } else {
        printf('Document %s does not exist!' . PHP_EOL, $snapshot->id());
    }
}

我不能去 else 块。 如果我将 where('capital', '=', true) 更改为 where('capital', '=', 'test'),条件应该为假并且我输入 else 块,因为文档 no '不存在。

但是我有一个空白页。 有人可以向我解释一下吗? 谢谢。

2 个答案:

答案 0 :(得分:0)

查询已经只返回集合中确实与您的查询匹配的那些文档,这就是结果集中的每个文档都存在的原因。

  • $citiesRef->where('capital', '=', true); 仅返回存在字段 capital 的文档,而不管值如何(= 示例数据集中的所有文档 - 不会返回没有 capital 字段的文档)
  • $citiesRef->where('capital', '=', 'test'); 仅返回字段 capital 等于 test(= 无文档)的文档

因此,您甚至不需要输入 if 条件:返回的文档集合为空。

当您尝试通过 ID 直接访问文档时,$document->exists() 方法很有用:

$doc = $citiesRef->document('non-existing-document-id') 仍会返回 DocumentReference 对象,但此处 $doc->exists() 会返回 false。

长话短说?,你可以从循环中移除条件:

$citiesRef = $db->collection('cities');
$query = $citiesRef->where('capital', '=', true);
$documents = $query->documents();

foreach ($documents as $document) {
    printf('Document data for document %s:' . PHP_EOL, $document->id());
    print_r($document->data());
    printf(PHP_EOL);
}

并尝试此操作以确认 exists() 方法按预期工作:

$doc = $citiesRef->document('test')->snapshot();

if ($doc->exists()) {
    printf('The document with ID "%s" exists.'.PHP_EOL, $doc->id());
} else {
    printf('The document with ID "%s" does NOT exist.'.PHP_EOL, $doc->id());
}

答案 1 :(得分:0)

在你的第一个条件下,

  • where('capital', '=', true)

它进入 forEach 块,因为它返回一些匹配的文档。即)$documents 的长度是 > 0

  • where('capital', '=', 'test')

这不会进入 forEach 循环,因为没有从 firestore 检索到匹配的文档。即)$documents 的长度是 == 0

因此,在迭代 $documents 之前,您必须检查检索到的 $documents 是否为空或其中是否包含任何文档。

在 JS 中,(因为我不懂 PHP)

if (documents.empty) {
  console.log('No matching documents.');
  return;
}  

documents.forEach(doc => {
  console.log(doc.id, '=>', doc.data());
});
  • 调用 exists() 很有用,仅当您通过引用检索文档时。如果 DocumentReference 引用的位置没有文档,则生成的文档将为空,对其调用 exists() 将返回 false。