📜 ⬆️ ⬇️

Personal experience with Firebase Cloud Firestore

Hello! Recently, I increasingly use Firebase in my projects: it is very convenient to do without actually writing the server part. I want to share some experience on the frontend side. In this case, it is Angular, so the official AngularFire library is used . I’ll note in advance that Android is better with libraries and the implementation of Firebase capabilities, as it seemed to me.


More about Firestore


The first is offline data. It is enabled by default in Android and iOS, but it is disabled for the web, and this was not surprising. I absolutely didn’t like this opportunity today, since the data was not updated (but should have been) even after the page was reloaded, and there are no clear controls (at least in the documentation) for cleaning or updating them. They are stored in IndexedDB, they can be manually cleared, however, the firebase is constantly connected to the database. Those. almost the only way for a user to delete (== clear in this case) only at the beginning of the page loading, when the firebase is not yet initialized. Therefore, I solved the problem by clicking on the window.location.href += '?clear'; , then after reloading the page in the main html file by executing such a high-priority script:


 <body> <script> if (window.location.href.indexOf('?clear') !== -1) { window.history.replaceState(null, null, window.location.pathname); var request = window.indexedDB.deleteDatabase("firestore/[DEFAULT]/your-project/main"); request.onsuccess = function() { console.log("Cleared cache successfully"); }; request.onerror = function() { console.log("Couldn't clear cache"); }; request.onblocked = function() { console.log("Couldn't clear cache due to the operation being blocked"); }; } else { console.log("Missing clear cache"); } </script> <!-- root     --> <root></root> </body> 

It works, but I will not say that it solves the main problems, since synchronization is just awfully implemented.


Secondly, do not use valueChanges for collection and document, since in 99% of cases metadata is necessary (it turns out). It is hard to memorize the uid of a document in any of its fields; the best way is to use snapshotChanges with a map to get a direct uid, like here for Angular:


 this.store.collection<any>("yourCollection", ref => { return ref.orderBy("yourFiled"); }).snapshotChanges() .map(actions => { return actions.map(action => { return { _uid: action.payload.doc.id, ...action.payload.doc.data() }; }); }) 

I would also like to note that collections and documents are independent of each other, i.e. when you select a document, you will not receive its subcollections: these are separate data, and this is done simply for the convenience of data presentation (one of the main differences from the Realtime Database).
Here when designing the database, take into account the document size limit of 1 MB. And if there can be a lot of data (of some kind of array), then we need to put them in the subcollection.


More about Angular


An important question was about saving the document so as not to overwrite other fields. Actually, I found this solution:


 this.store.collection(collection) .doc(document).ref .set(object, { merge: true }) .then(() => this.showSnackbar(" ")) .catch((error) => { console.log(error); this.showSnackbar("   "); }); // ,  showSnackbar       showSnackbar = (message) => { this.snackbar.open(message, null, { duration: 1000 }); }; 

To save Firebase resources (thanks to the excellent implementation of Offline Data), I store the data in the ReplaySubject buffer. Everything is good, but it is impossible to clear it when updating data, so you have to recreate it:


 clearDocuments() { this._documents.complete(); this._documents = null; this._documents = new ReplaySubject(); this._refresh.next(true); } 

Here _refresh is BehaviorSubject , switchMap is perfectly combined with it:


 this.service._refresh.asObservable() .switchMap(() => { this.items.data = []; return this.service._documents.asObservable(); }) .subscribe(document => { }); 

Small personal impression


I have had experience with the Realtime Database and will say that the Firestore is a more advanced repository, although it may have its drawbacks. Even in terms of working in the console (it happened by mistake to delete the root node of the Realtime Database)
There is no online emulator of rules in the Firestore (no one has canceled the actual tests), so I use the firestore-security-tests library for testing. It works great, only, this type of get(/databases/$(database)/documents/info/app).data.version not supported.
I hope with the release of Firestore everything will change for the better.


Addition


It’s impossible to connect Firebase with admin rights for the internal site (and because of this you have to hardcod with the rules, the only good thing is that you can specify the signature of the application certificate and so on in the console). There is a solution for Node.js, but somehow it was not possible to implement it yet. Can anyone have this experience?


')

Source: https://habr.com/ru/post/348366/


All Articles