-
-
Save jasonbyrne/6b63e7d59c5ed97ef95ff2c78791cfae to your computer and use it in GitHub Desktop.
<?php | |
namespace PHPFireStore { | |
class FireStoreDocument { | |
private $fields = []; | |
private $name = null; | |
private $createTime = null; | |
private $updateTime = null; | |
/** | |
Example: | |
{ | |
"name": "projects/{project_id}/databases/(default)/documents/{collectionName}/{documentId}", | |
"fields": { | |
"hello": { | |
"doubleValue": 3 | |
} | |
}, | |
"createTime": "2017-10-18T21:27:33.186235Z", | |
"updateTime": "2017-10-18T21:27:33.186235Z" | |
} | |
*/ | |
public function __construct($json=null) { | |
if ($json !== null) { | |
$data = json_decode($json, true, 16); | |
// Meta properties | |
$this->name = $data['name']; | |
$this->createTime = $data['createTime']; | |
$this->updateTime = $data['updateTime']; | |
// Fields | |
foreach ($data['fields'] as $fieldName => $value) { | |
$this->fields[$fieldName] = $value; | |
} | |
} | |
} | |
public function getName() { | |
return $this->name; | |
} | |
public function setString($fieldName, $value) { | |
$this->fields[$fieldName] = [ | |
'stringValue' => $value | |
]; | |
} | |
public function setDouble($fieldName, $value) { | |
$this->fields[$fieldName] = [ | |
'doubleValue' => floatval($value) | |
]; | |
} | |
public function setArray($fieldName, $value) { | |
$this->fields[$fieldName] = [ | |
'arrayValue' => $value | |
]; | |
} | |
public function setBoolean($fieldName, $value) { | |
$this->fields[$fieldName] = [ | |
'booleanValue' => !!$value | |
]; | |
} | |
public function setInteger($fieldName, $value) { | |
$this->fields[$fieldName] = [ | |
'integerValue' => intval($value) | |
]; | |
} | |
public function get($fieldName) { | |
if (array_key_exists($fieldName, $this->fields)) { | |
return reset($this->fields); | |
} | |
throw new Exception('No such field'); | |
} | |
public function toJson() { | |
return json_encode([ | |
'fields' => $this->fields | |
]); | |
} | |
} | |
class FireStoreApiClient { | |
private $apiRoot = 'https://firestore.googleapis.com/v1beta1/'; | |
private $project; | |
private $apiKey; | |
function __construct($project, $apiKey) { | |
$this->project = $project; | |
$this->apiKey = $apiKey; | |
} | |
private function constructUrl($method, $params=null) { | |
$params = is_array($params) ? $params : []; | |
return ( | |
$this->apiRoot . 'projects/' . $this->project . '/' . | |
'databases/(default)/' . $method . '?key=' . $this->apiKey . '&' . http_build_query($params) | |
); | |
} | |
private function get($method, $params=null) { | |
$curl = curl_init(); | |
curl_setopt_array($curl, array( | |
CURLOPT_RETURNTRANSFER => 1, | |
CURLOPT_URL => $this->constructUrl($method, $params), | |
CURLOPT_USERAGENT => 'cURL' | |
)); | |
$response = curl_exec($curl); | |
curl_close($curl); | |
return $response; | |
} | |
private function post($method, $params, $postBody) { | |
$curl = curl_init(); | |
curl_setopt_array($curl, array( | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_URL => $this->constructUrl($method, $params), | |
CURLOPT_HTTPHEADER => array('Content-Type: application/json','Content-Length: ' . strlen($postBody)), | |
CURLOPT_USERAGENT => 'cURL', | |
CURLOPT_POST => true, | |
CURLOPT_POSTFIELDS => $postBody | |
)); | |
$response = curl_exec($curl); | |
curl_close($curl); | |
return $response; | |
} | |
private function put($method, $params, $postBody) { | |
$curl = curl_init(); | |
curl_setopt_array($curl, array( | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_CUSTOMREQUEST => 'PUT', | |
CURLOPT_HTTPHEADER => array('Content-Type: application/json','Content-Length: ' . strlen($postBody)), | |
CURLOPT_URL => $this->constructUrl($method, $params), | |
CURLOPT_USERAGENT => 'cURL', | |
CURLOPT_POSTFIELDS => $postBody | |
)); | |
$response = curl_exec($curl); | |
curl_close($curl); | |
return $response; | |
} | |
private function patch($method, $params, $postBody) { | |
$curl = curl_init(); | |
curl_setopt_array($curl, array( | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_CUSTOMREQUEST => 'PATCH', | |
CURLOPT_HTTPHEADER => array('Content-Type: application/json','Content-Length: ' . strlen($postBody)), | |
CURLOPT_URL => $this->constructUrl($method, $params), | |
CURLOPT_USERAGENT => 'cURL', | |
CURLOPT_POSTFIELDS => $postBody | |
)); | |
$response = curl_exec($curl); | |
curl_close($curl); | |
return $response; | |
} | |
private function delete($method, $params) { | |
$curl = curl_init(); | |
curl_setopt_array($curl, array( | |
CURLOPT_RETURNTRANSFER => 1, | |
CURLOPT_CUSTOMREQUEST => 'DELETE', | |
CURLOPT_URL => $this->constructUrl($method, $params), | |
CURLOPT_USERAGENT => 'cURL' | |
)); | |
$response = curl_exec($curl); | |
curl_close($curl); | |
return $response; | |
} | |
public function getDocument($collectionName, $documentId) { | |
if ($response = $this->get("documents/$collectionName/$documentId")) { | |
return new FireStoreDocument($response); | |
} | |
} | |
/** | |
This does not work | |
*/ | |
public function setDocument($collectionName, $documentId, $document) { | |
return $this->put( | |
"documents/$collectionName/$documentId", | |
[ ], | |
$document->toJson() | |
); | |
} | |
public function updateDocument($collectionName, $documentId, $document, $documentExists=null) { | |
$params = []; | |
if ($documentExists !== null) { | |
$params['currentDocument.exists'] = !!$documentExists; | |
} | |
return $this->patch( | |
"documents/$collectionName/$documentId", | |
$params, | |
$document->toJson() | |
); | |
} | |
public function deleteDocument($collectionName, $documentId) { | |
return $this->delete( | |
"documents/$collectionName/$documentId", [] | |
); | |
} | |
public function addDocument($collectionName, $document) { | |
return $this->post( | |
"documents/$collectionName", | |
[], | |
$document->toJson() | |
); | |
} | |
} | |
} |
@Meistercoach83 I didn't debug this library extensively... since it was just a proof of concept. Did you try it as a regular array, rather than an associative array? Like [ "foo", "bar" ]
If that doesn't work, it may need to actually be something like this
[ { "stringValue": "foo" }, { "stringValue": "bar } ]
Again, I haven't tested this just suggestion that may work. Would be cool if we forked this and made it a real library with unit tests and documentation.
Setting arrays works just fine, this is how you can do that with this class cleanly, btw thanks for making this available... it made things much easier:
<?php
$var = [];
$var['values'][] = ['integerValue' => 10];
$document->setArray('myvar', $var);
?>
You can also add a setMap function:
public function setMap($fieldName, $value){
$this->fields[$fieldName] = [
'mapValue' => $value
];
}
use it like this
$fields['fields'] = ['test' => ['stringValue' => 'test']];
$document->setMap('resultoptions', $fields );
Hi, I am using this library, but I did not understand how to use code to update record which already present int Firebase collection. If anyone can help?
@alvinsalenga I haven't followed up to try this again. I reached out to some Google Firestore team on Twitter to report the seemingly bug, but they did not get back to me about it.