├── src
├── config
│ └── laravel-firebase.php
├── HttpHandler
│ ├── FirebaseInterface.php
│ ├── HttpHandlerFactory.php
│ ├── Guzzle5HttpHandler.php
│ └── Guzzle6HttpHandler.php
├── Provider
│ └── FirebaseServiceProvider.php
├── Subscribers
│ └── EnsureJson.php
├── GoogleConsole.php
├── Middleware
│ └── EnsureJson.php
└── Firebase.php
├── .idea
└── vcs.xml
├── tests
├── unit
│ └── SampleTest.php
└── _env
│ └── ServiceAccount.json
├── phpunit.xml
├── composer.json
└── README.md
/src/config/laravel-firebase.php:
--------------------------------------------------------------------------------
1 | storage_path('app/secret_file.json')
6 |
7 | ];
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/tests/unit/SampleTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
10 | }
11 |
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/HttpHandler/FirebaseInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 | tests
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Provider/FirebaseServiceProvider.php:
--------------------------------------------------------------------------------
1 | publishes([
14 | __DIR__.'/../config/laravel-firebase.php' => config_path('laravel-firebase.php'),
15 | ], 'config');
16 |
17 | }
18 |
19 | public function register() {
20 |
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/src/Subscribers/EnsureJson.php:
--------------------------------------------------------------------------------
1 | getRequest();
15 | }
16 |
17 | /**
18 | * @return array
19 | */
20 | public function getEvents()
21 | {
22 | return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST]];
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/tests/_env/ServiceAccount.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "service_account",
3 | "project_id": "project",
4 | "private_key_id": "private_key_id",
5 | "private_key": "-----BEGIN PRIVATE KEY-----ADD KEY HERE-----END PRIVATE KEY-----\n",
6 | "client_email": "client@email.tld",
7 | "client_id": "1234567890",
8 | "auth_uri": "https://some.google.tld/o/oauth2/auth",
9 | "token_uri": "https://some.google.tld/o/oauth2/token",
10 | "auth_provider_x509_cert_url": "https://some.google.tld/oauth2/v1/certs",
11 | "client_x509_cert_url": "https://some.google.tld/robot/v1/metadata/x509/user%40project.iam.gserviceaccount.com"
12 | }
13 |
--------------------------------------------------------------------------------
/src/HttpHandler/HttpHandlerFactory.php:
--------------------------------------------------------------------------------
1 | =5.3.0",
14 | "guzzlehttp/guzzle": "~5.3|~6.0",
15 | "guzzlehttp/psr7": "~1.2",
16 | "illuminate/support": "^5.2.8"
17 |
18 | },
19 | "authors": [
20 | {
21 | "name": "Luqman",
22 | "email": "luqmanrom@gmail.com"
23 | }
24 | ],
25 | "autoload": {
26 | "psr-4": {
27 | "Geckob\\Firebase\\": "src"
28 | }
29 | },
30 | "require-dev": {
31 | "phpunit/phpunit": "^6"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/GoogleConsole.php:
--------------------------------------------------------------------------------
1 | scopes = [
15 | 'https://www.googleapis.com/auth/userinfo.email',
16 | 'https://www.googleapis.com/auth/firebase.database',
17 | ];
18 |
19 | $this->credentials = [
20 | 'client_email' => $config['client_email'],
21 | 'client_id' => $config['client_id'],
22 | 'private_key' => $config['private_key'],
23 | ];
24 | }
25 |
26 | public function getCredentials()
27 | {
28 | return $this->credentials;
29 | }
30 |
31 | public function getScopes()
32 | {
33 | return $this->scopes;
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/src/Middleware/EnsureJson.php:
--------------------------------------------------------------------------------
1 | getUri();
15 | $path = $uri->getPath();
16 |
17 | if (substr($path, -5) !== '.json') {
18 | $uri = $uri->withPath($path.'.json');
19 | $request = $request->withUri($uri);
20 | }
21 |
22 | $request = $request->withHeader('Content-Type', 'application/json');
23 |
24 | return $handler($request, $options);
25 | };
26 | };
27 | }
28 |
29 |
30 |
31 | }
--------------------------------------------------------------------------------
/src/Firebase.php:
--------------------------------------------------------------------------------
1 | 0])
18 | {
19 | if (func_num_args() == 0) {
20 | $secretFilePath = config('laravel-firebase.secretPath');
21 | }
22 |
23 | $this->config = array_merge($this->extractSecrets($secretFilePath), $config);
24 |
25 | $googleConsole = new GoogleConsole($this->config);
26 |
27 | $this->httpClient = HttpHandlerFactory::setup($this->config, $this->path, $googleConsole);
28 |
29 | }
30 |
31 | private function extractSecrets($secretFilePath)
32 | {
33 | $config = file_get_contents($secretFilePath);
34 | return json_decode($config, true);
35 | }
36 |
37 | public function setPath($path)
38 | {
39 | $this->path = $path;
40 |
41 | $this->httpClient->setPath($path);
42 |
43 | return $this;
44 | }
45 |
46 |
47 | public function set($key, $value)
48 | {
49 | $this->httpClient->set($key, $value);
50 | }
51 |
52 | public function get($key)
53 | {
54 | return $this->httpClient->get($key);
55 | }
56 |
57 | public function delete($key)
58 | {
59 | $this->httpClient->delete($key);
60 | }
61 |
62 | public function push($arr)
63 | {
64 | $this->httpClient->push($arr);
65 | }
66 |
67 |
68 | }
--------------------------------------------------------------------------------
/src/HttpHandler/Guzzle5HttpHandler.php:
--------------------------------------------------------------------------------
1 | config = $config;
26 |
27 | $this->databaseUri = sprintf('https://%s.firebaseio.com/', $this->config['project_id']);
28 |
29 | $this->http = new Client([
30 | 'base_url' => $this->databaseUri,
31 | 'defaults' => [
32 | 'auth' => 'google_auth'
33 | ]
34 | ]);
35 |
36 | $this->http->getEmitter()->attach(new AuthTokenSubscriber(
37 | new ServiceAccountCredentials(
38 | $googleConsole->getScopes(),
39 | $googleConsole->getCredentials()
40 | )));
41 | }
42 |
43 | public function setPath($path)
44 | {
45 | $this->path = $path;
46 | }
47 |
48 | public function set($key, $value)
49 | {
50 | $response = $this->http->put($this->path . $key . '.json',
51 | ['body' => json_encode($value), 'timeout' => $this->config['timeout']]);
52 |
53 | return (string) $response->getBody();
54 |
55 | }
56 |
57 | public function get($key)
58 | {
59 | $response = $this->http->get($this->path. $key . '.json', ['timeout' => $this->config['timeout']]);
60 |
61 | return (string) $response->getBody();
62 |
63 |
64 | }
65 |
66 | public function delete($key)
67 | {
68 | $response = $this->http->delete($this->path. $key . '.json', ['timeout' => $this->config['timeout']]);
69 |
70 | return (string) $response->getBody();
71 | }
72 |
73 | public function push($arr)
74 | {
75 | $response = $this->http->post($this->path . '.json',
76 | ['body' => json_encode($arr), 'timeout' => $this->config['timeout']]);
77 |
78 | return (string) $response->getBody();
79 | }
80 |
81 | }
--------------------------------------------------------------------------------
/src/HttpHandler/Guzzle6HttpHandler.php:
--------------------------------------------------------------------------------
1 | config = $config;
28 |
29 | $this->databaseUri = new Uri(sprintf('https://%s.firebaseio.com', $this->config['project_id']));
30 |
31 | $googleAuthTokenMiddleware = new AuthTokenMiddleware(
32 | new ServiceAccountCredentials(
33 | $googleConsole->getScopes(),
34 | $googleConsole->getCredentials()
35 | ));
36 |
37 | $stack = HandlerStack::create();
38 | $stack->push(EnsureJson::run(), 'ensure_json');
39 | $stack->push($googleAuthTokenMiddleware, 'auth_service_account');
40 |
41 | $this->http = new Client([
42 | 'base_uri' => $this->databaseUri,
43 | 'handler' => $stack,
44 | 'auth' => 'google_auth',
45 | ]);
46 |
47 | }
48 |
49 | public function setPath($path) {
50 | $this->path = $path;
51 | }
52 |
53 | public function set($key, $value)
54 | {
55 |
56 | $response = $this->http->request('PUT', $this->databaseUri->withPath($this->path.$key),
57 | ['body' => json_encode($value), 'timeout' => $this->config['timeout']]
58 | );
59 |
60 | return $response->getBody()->getContents();
61 |
62 |
63 | }
64 |
65 | public function get($key)
66 | {
67 |
68 | $response = $this->http->request('GET', $this->databaseUri->withPath($this->path. $key,
69 | ['timeout' => $this->config['timeout']]));
70 |
71 | return $response->getBody()->getContents();
72 |
73 | }
74 |
75 | public function delete($key)
76 | {
77 | $response = $this->http->request('DELETE', $this->databaseUri->withPath($this->path. $key,
78 | ['timeout' => $this->config['timeout']]));
79 |
80 | return $response->getBody()->getContents();
81 | }
82 |
83 | public function push($arr)
84 | {
85 | $response = $this->http->request('POST', $this->databaseUri->withPath($this->path),
86 | ['body' => json_encode($arr), 'timeout' => $this->config['timeout']]);
87 |
88 | return $response->getBody()->getContents();
89 | }
90 |
91 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Firebase PHP Wrapper
2 |
3 |
4 | [](https://packagist.org/packages/geckob/firebase)
5 |
6 |
7 | This package makes the authentication and the basic CRUD
8 | operation on Firebase Database as simple as possible.
9 | For now, it supports both Guzzle 5 and Guzzle 6.
10 |
11 |
12 | ## Installation
13 |
14 | The easiest way it via Composer
15 |
16 | ```
17 | composer require geckob/firebase
18 | ```
19 |
20 | ## Usages
21 |
22 |
23 | ### 1. Authentication
24 |
25 | **1.1 Generate Service Account secret file**
26 |
27 | This package supported authentication using secrets file generated in the Service Account page.
28 |
29 | To generate the secret file, follow this steps
30 |
31 | 1. Go to [Firebase Console](https://console.firebase.google.com/)
32 | 2. Choose your project
33 | 3. Click the gear icon and go to Project Settings
34 | 4. Click the Service Accounts tab
35 | 5. Scroll down and click "Generate New Private Key" button. Save it to somewhere secure but
36 | accessible for your internal server
37 |
38 | **1.2 Use the secret file to authenticate**
39 |
40 | ```php
41 | $firebase = new \Geckob\Firebase\Firebase('path_to_your_secret_file.json');
42 | ```
43 | ### 2. CRUD Operation
44 |
45 | The CRUD operation on Firebase Database is based on the [Firebase REST API Docs](https://www.firebase.com/docs/rest-api.html).
46 |
47 | Assuming the authentication is succesfully done,
48 |
49 | ```php
50 | // Set the parent node.
51 | $firebase = $firebase->setPath('bookings/');
52 |
53 | // Create a new node with key = test and value = testValue.
54 | // If the node already exist, it will update the value
55 | $firebase->set('test','testValue');
56 |
57 | // Support multiple nodes, if it doesnt exist, it will create the node
58 | $firebase->set('testObject/testKey', 'testValueObject');
59 |
60 |
61 | // Same as set but without keys. This requires to call setPath first to identify the parent
62 | $firebase->push([
63 | 'test' => 'value',
64 | 'test1' => 'value1'
65 | ]);
66 |
67 | // Get the value of node with key = test
68 | $firebase->get('test');
69 |
70 | // Get the value of using multilevel key
71 | $firebase->get('testObject/testKey');
72 |
73 |
74 |
75 |
76 | // Delete the node with key = test
77 | $firebase->delete('test');
78 |
79 | // Delete the multilevel node and all it's children
80 | $firebase->delete('testObject/testKey');
81 |
82 |
83 | ```
84 |
85 | //
86 |
87 | ## Others
88 |
89 | This package works perfectly fine for my use case for now. Should you have any other
90 | use cases that requires me to extend the features, or suggestions how this package
91 | can be improved, feel free to open issues or email me at luqmanrom@gmail.com
92 |
93 |
94 | ## License
95 |
96 | #### The MIT License (MIT)
97 | ```
98 | Copyright (c) 2012-2016 Tamas Kalman
99 |
100 | Permission is hereby granted, free of charge, to any person obtaining a copy
101 | of this software and associated documentation files (the "Software"), to deal
102 | in the Software without restriction, including without limitation the rights
103 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
104 | copies of the Software, and to permit persons to whom the Software is
105 | furnished to do so, subject to the following conditions:
106 |
107 | The above copyright notice and this permission notice shall be included in
108 | all copies or substantial portions of the Software.
109 |
110 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
111 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
112 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
113 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
114 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
115 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
116 | THE SOFTWARE.
117 | ```
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------