Firebase PHP 将地图添加到数组

Firebase PHP Adding Map to Array

我正在尝试将 Firebase PHP API 用于 update/append 带有地图的文档字段数组

我在 Python 中有以下代码可以正常工作

ref = db.collection(u'jobs').document(jobId)
                ref.update({
                        u'messages': firestore.ArrayUnion([{
                                u'category': u'0',
                                u'message': u'TEST',
                                u'sender': u'TEAM',
                                }])
                        })

虽然当我尝试在 PHP 中复制它时,它不起作用。我尝试了很多不同的方法来查看错误,但我得到的只是 500 INTERNAL SERVER ERROR。

require 'vendor/autoload.php';
use Google\Cloud\Firestore\FirestoreClient;
use Google\Cloud\Firestore\FieldValue;
$firestore = new FirestoreClient([
    'projectId' => 'XXX-XX',
    'credentials' => 'key.json'
]);


$jobId = "XXXX";
$docRef = $firestore->collection('jobs')->document($jobId);
$docRef->update([
        'messages' => FieldValue::arrayUnion([{
            'category' : '0',
            'message' : 'TEST',
            'sender' : 'TEAM',
        }])
]);

我抬头samples of Array Union in PHP, adding data with PHP。我尝试了很多 :=>arrayUnion([])arrayUnion({[]}) 的变体,但都无济于事。

知道是什么原因造成的吗?

From Firebase Documentation:

$cityRef = $db->collection('cities')->document('DC');

// Atomically add a new region to the "regions" array field.
$cityRef->update([
    ['path' => 'regions', 'value' => FieldValue::arrayUnion(['greater_virginia'])]
]);

I would assume you would like something like this:

$docRef = $firestore->collection('jobs')->document($jobId);

// Atomically add new values to the "messages" array field. 
$docRef->update([
        ['path' => 'messages', 'value' => FieldValue::arrayUnion([[
            'category' : '0',
            'message' : 'TEST',
            'sender' : 'TEAM',
        ]])]
]);

这里似乎有一些问题。

首先,PHP 将数组用于地图和“普通”数组。 PHP 中没有对象字面量 ({})。数组值是使用 => 运算符指定的,而不是 :.

其次,DocumentReference::update() 接受您希望更改的值列表,以及路径和值。所以更新调用看起来像这样:

$docRef->update([
    ['path' => 'foo', 'value' => 'bar']
]);

您可以使用 DocumentReference::set() 来实现您想要的行为。如果文档不存在,set() 将创建一个文档,如果文档不存在,update() 将引发错误。 set() 还将替换文档中的所有现有字段,除非您指定合并行为:

$docRef->set([
    'foo' => 'bar'
], ['merge' => true]);

因此,您的代码可以重写为以下任一形式:

$jobId = "XXXX";
$docRef = $firestore->collection('jobs')->document($jobId);
$docRef->set([
    'messages' => FieldValue::arrayUnion([[
        'category' => '0',
        'message' => 'TEST',
        'sender' => 'TEAM',
    ]])
], ['merge' => true]);
$jobId = "XXXX";
$docRef = $firestore->collection('jobs')->document($jobId);
$docRef->update([
    [
        'path' => 'messages', 'value' => FieldValue::arrayUnion([[
            'category' => '0',
            'message' => 'TEST',
            'sender' => 'TEAM',
        ]])
    ]
]);

最后一件事要注意:arrayUnion 不会附加重复值。因此,如果您提供的值(包括嵌套映射中的所有键和值)已经存在,则不会将其附加到文档中。

如果您还没有,请在您的开发环境中打开错误报告以接收有关代码失败原因的信息。 PHP 会通知您您的代码段中包含的解析错误,而 Firestore 客户端会为您提供通常非常有用的错误。