Introduction
Since you are here, you probably heard or worked with Firebase, and firestore is one of their Eco-system. In today's article, we'll learn how to: add, edit, remove and fetch data from firestore collections
Requisites
Setting up Firebase Project
First thing you would probably do, is creating a new Firebase project, and if you don't know how, you may go to get Firebase instruction from Google official documentation.
Installing Firebase package
We'll use kreait/laravel-firebase
package.
In your app, require the above package by
1composer require kreait/laravel-firebase
After that, you may add the package's service provider:
1<?php 2// config/app.php 3return [ 4 // ... 5 'providers' => [ 6 // ... 7 Kreait\Laravel\Firebase\ServiceProvider::class 8 ] 9 // ...10];
Package Configuration
You need to add the Firebase credentials in order to use the package
1# relative or full path to the Service Account JSON file2FIREBASE_CREDENTIALS=3# You can find the database URL for your project at4# https://console.firebase.google.com/project/_/database5FIREBASE_DATABASE_URL=https://<your-project>.firebaseio.com
If you want to know more, take a look at the package instructions
In order to work with firestore features, you need to install grpc extension
CRUD Operations
After you set up all above requirements. Now let's start to have some fun 😃
First, Create a collection in firestore cloud
Fetch Documents from the collection
In order to fetch a specific collection, do the following
1public function index() 2{ 3 $data = app('firebase.firestore') 4 ->database() 5 ->collection('categories') 6 ->documents(); 7 8 if ($data->isEmpty()) { 9 return collect();10 }11 12 $categories = collect($data->rows());13 14 return view('categories.index', [15 'categories' => $categories,16 ]);17}
Here we are fetching the items from a categories
collection (replace the categories
with any collection you created)
In order to fetch the data after you loop through the collection, do the following:
1@foreach($categories as $category)2 <!--3 The `key` here is the key inside4 your collection, it may be `id`, `name`... etc5 -->6 {{ $category->resource->data()['key']}}7@endforeach
Create New Document
In order to create an document
inside the collection, do the following
1public function store(CategoryRequest $request) 2{ 3 $firestore = app('firebase.firestore') 4 ->database() 5 ->collection('categories') 6 ->newDocument(); 7 8 $firestore->set($request->validated()); 9 10 // Redirect, Success message...11}
In this example, we're validating the requested data
first, through CategoryResource
, then we store it inside the firestore
collection.
Edit Existing Document
To edit an existing document, simply, you need to fetch the document ID, and override the data. Here's an example:
1public function update(CategoryRequest $request) 2{ 3 $firestore = app('firebase.firestore') 4 ->database() 5 ->collection('categories') 6 ->document('WpVqG3LEOBdXzb2vzSBt'); 7 8 $firestore->set($request->validated); 9 10 // Redirect, success message...11}
Each created document has a unique ID, and here, we are specifying the collection, then the document. After that, we override the existing data.
Note: Firestore is flixible on writing documents,if you for example have/has:
id
,name
, and when you edit, you update just theid
. Thename
will be removed automatically.
Delete Document
Deleting document
is like editing it, get the collection/document then delete.
Here's an example:
1app('firebase.firestore')2 ->database()3 ->collection('categories')4 ->document('WpVqG3LEOBdXzb2vzSBt')5 ->delete();
Our journey end up here, and you are all set to be working with firestore API, if you like to optimize/refactor code (like me), take a look at the bellow sections.
Firestore Repository
When I'm developing a web app, I like to keep most of the things under control, and avoiding the DRY
principle. So, when you are about to edit/add a feature or upgrade your codebase
in the future, you'll modify one file, instead of modifying 20+ files.
In order to use these methods easily inside your app, without repetition, I created a repository
, does something like this
1public function index(FirestoreRepository $firestore)2{3 $categories = $firestore->fetch('categories');4 5 // ...6}
Creating the Interface
First you need to create an interface called Firestore
(or any name you prefer), inside app/Services/Firebase/Contracts
(or any structure you prefer really!).
1<?php 2 3namespace App\Services\Firebase\Firestore\Contracts; 4 5use Illuminate\Support\Collection; 6 7interface FireStore 8{ 9 /**10 * Create New Collection Item11 *12 * @var string $collection13 * @var array $data14 *15 * @return array16 */17 public function create(string $collection, array $data): array;18 19 /**20 * Fetch Existing Collection Items21 *22 * @var string $collection23 * @return Illuminate\Support\Collection24 */25 public function fetch(string $collection): Collection;26 27 /**28 * Edit Existing Item in a collection29 *30 * @var string $collection31 * @var string $document32 * @var array $data33 *34 * @return array35 */36 public function edit(string $collection, string $document, array $data): array;37 38 /**39 * Delete Existing Collection40 *41 * @var string $collection42 * @var string $document43 *44 * @return void45 */46 public function destory(string $collection, string $document): void;47}
The Firestore Class
After creating the interface, we need to create FirestoreRepository
class, in order to use the methods.
Here's the class
1<?php 2 3namespace App\Services\Firebase\Firestore; 4 5use App\Services\Firebase\Firestore\Contracts\FireStore; 6use Illuminate\Support\Collection; 7 8final class FirestoreRepository implements FireStore 9{10 public function create(string $collection, array $data): array
11 {12 $firestore = app('firebase.firestore')13 ->database()14 ->collection($collection)15 ->newDocument();16 17 return $firestore->set($data);18 } 19 20 public function fetch(string $collection): Collection
21 {22 $data = app('firebase.firestore')23 ->database()24 ->collection($collection)25 ->documents();26 27 if ($data->isEmpty()) {28 return collect();29 }30 31 return collect($data->rows());32 } 33 34 public function edit(string $collection, string $document, array $data): array
35 {36 $firestore = app('firebase.firestore')37 ->database()38 ->collection($collection)39 ->document($document);40 41 $document = $firestore->set($data);42 43 return $document;44 } 45 46 public function destory(string $collection, string $document): void
47 {48 app('firebase.firestore')49 ->database()50 ->collection($collection)51 ->document($document)52 ->delete();53 } 54}
Using The Class
After you create all of that, you are free to use the class as Dependency Injection
class, and you can use this class in the construct
method, or in the method
directly
1// ... 2class CategoryController extends Controller 3{ 4 /** 5 protected $firestore; 6 7 public function __construct(FirestoreRepository $firestore) 8 { 9 $this->firestore = $firestore; 10 }11 12 public function index()13 {14 $categories = $this->firestore->fetch('categories'); 15 //...16 }17}
Or in a method like this
1// ...2public function index(FirestoreRepository $firestore) 3{4 $categories = $firestore->fetch('categories'); 5 6 //...7}
Conclusion
We learned in this article, about how to do a CRUD operation using Laravel and firestore API's, and if you enjoyed this article, please share it with others.
If you are interested in Laravel topics, or tech in general, make sure to follow me on Twitter for daily tips on web developments.
Don't forget to do something kind today.