Firebase PHP Добавление карты в массив - PullRequest
0 голосов
/ 14 октября 2019

Я пытаюсь использовать PHP API Firebase для обновления / добавления массива поля документа с картой

У меня есть следующий код в 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.

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',
        }])
]);

Я просмотрел образцов Array Union в PHP , , добавив данные с помощью PHP . Я пробовал множество вариантов : или => или arrayUnion([]) или arrayUnion({[]}) безрезультатно.

Есть идеи, что вызвало это?

Ответы [ 2 ]

0 голосов
/ 14 октября 2019

Похоже, что здесь происходит несколько проблем.

Во-первых, 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 сообщит вам об ошибках, которые часто могут быть весьма полезны.

0 голосов
/ 14 октября 2019

Из Документация Firebase :

$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'])]
]);

Я хотел бы предположить, что вы хотели бы что-то вроде этого:

$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',
        ]])]
]);
...