{"id":1312,"date":"2017-11-13T15:11:27","date_gmt":"2017-11-13T14:11:27","guid":{"rendered":"https:\/\/blog.thecodecampus.de\/?p=1312"},"modified":"2022-03-14T14:29:58","modified_gmt":"2022-03-14T13:29:58","slug":"getting-started-firestore-angularfire2","status":"publish","type":"post","link":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/","title":{"rendered":"Getting started with Firestore and AngularFire2"},"content":{"rendered":"<p><a href=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1356 size-large\" src=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg\" alt=\"Cloud Firestore\" width=\"1024\" height=\"576\" srcset=\"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg 1024w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/11\/maxresdefault-300x169.jpg 300w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/11\/maxresdefault-768x432.jpg 768w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/11\/maxresdefault.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>A few weeks ago, Google has released its new solution for building scalable cloud databases\u00a0\u2014 the Cloud Firestore. It has some nice improvements in comparison to their previous database (which used to be called Firebase but is now referred to as &#8216;Realtime Database&#8217;), like better data structuring and a more powerful querying API. In this post I&#8217;m going to go through everything you need to get started with Cloud Firestore in Angular with the official AngularFire2 library. So let&#8217;s get started!<\/p>\n<h1>Setup<\/h1>\n<h2>1. installation<\/h2>\n<p><span class=\"token p\">First things first, let&#8217;s set up a project. In this tutorial we want to build a little blog app where a user can manage their blog posts and save them to Firestore. So let&#8217;s go ahead and create a new project:<\/span><\/p>\n<pre class=\"lang:default decode:true\">ng new blog-app\r\ncd blog-app\r\n<\/pre>\n<p>Next thing we need to do is install the necessary packages and tools for our project.<\/p>\n<pre class=\"lang:default decode:true\">npm install firebase angularfire2 --save<\/pre>\n<p>In the first line we installed Firebase package itself plus AngularFire2, which is a wrapper that adds some neat Angular-specific features to Firebase. Those packages also include things like Firebase Authentication, Hosting etc. but for now we&#8217;re only concerned with Cloud Firestore.<\/p>\n<h2><span class=\"token h3\">2. Firebase console<\/span><\/h2>\n<p>In order to actually use Cloud Firestore we need to create a new Firebase project that our app can connect to. To do this, go to the <a href=\"https:\/\/console.firebase.google.com\">firebase console<\/a>, click on &#8216;add project&#8217; and fill in your project name. Once your project is set up, click on the &#8216;Database&#8217; tab and activate Cloud Firestore.<\/p>\n<p>The Database will then prompt you to select a security rule setting:<\/p>\n<p><a href=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/Screenshot-from-2017-11-14-10-43-02-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1343 size-full\" src=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/Screenshot-from-2017-11-14-10-43-02-1.png\" alt=\"security rule settings\" width=\"807\" height=\"531\" srcset=\"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/11\/Screenshot-from-2017-11-14-10-43-02-1.png 807w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/11\/Screenshot-from-2017-11-14-10-43-02-1-300x197.png 300w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/11\/Screenshot-from-2017-11-14-10-43-02-1-768x505.png 768w\" sizes=\"auto, (max-width: 807px) 100vw, 807px\" \/><\/a><\/p>\n<p>For now we&#8217;ll go with &#8220;start in test mode&#8221; which allows everyone (including us) to read and write to our database. When your app goes to production you should definitely consider changing your security rules to something more sane (<a href=\"https:\/\/firebase.google.com\/docs\/firestore\/security\/get-started\">learn more about security rules here<\/a>), but for our purposes this is good enough.<\/p>\n<p>The last thing we need in our console is our config data. For this, go back to &#8216;Project Overview&#8217; and click on &#8216;Add Firebase to your web app&#8217;. From the popup you&#8217;ll need to copy just the content of the config object. With that we can head back to our project.<\/p>\n<h2>3. project<\/h2>\n<p>Next we&#8217;ll need to provide the config to our Angular application. For this we&#8217;ll head to\u00a0<code>app\/src\/environment.ts<\/code>\u00a0 and create a field called\u00a0<code>firebase<\/code>\u00a0in which we&#8217;ll copy our config data, like this:<\/p>\n<pre class=\"lang:default decode:true\" title=\"src\/app\/environments\/environment.ts\">export const environment = {\r\n  production: false,\r\n  firebase: {\r\n    \/\/your config here\r\n  }\r\n};<\/pre>\n<p>Lastly we have to pass this config data to AngularFire2. Add the following line to the imports of your app.module.ts:<\/p>\n<pre class=\"lang:default decode:true\" title=\"app.module.ts\"> imports: [\r\n    ...\r\n    AngularFireModule.initializeApp(environment.firebase),\r\n ]<\/pre>\n<p>Now we&#8217;re all set and done and can start building our Firestore app!<\/p>\n<h1><span class=\"token h2\">creating a CRUD service<\/span><\/h1>\n<p><span class=\"token p\">We want to create a blog app where one can write posts (create), display them (read), rate them by giving likes (update) and deleting them again (delete). If you want to see the source code you can check out the <a href=\"https:\/\/github.com\/biowaffeln\/blog-app\">github repo<\/a>.\u00a0<\/span><\/p>\n<p><span class=\"token p\">Let&#8217;s start by creating a component to manage our posts and a F<\/span><span class=\"token p\">irestore service to add them to our database.<\/span><\/p>\n<pre class=\"lang:default decode:true\">ng generate component manage-posts\r\nng generate component view-posts\r\nng generate service post<\/pre>\n<p><span class=\"token p\">The manage-posts-component will be used to create and delete posts, the view-posts will read and update them.<\/span><\/p>\n<p><span class=\"token p\">Next we need a model to define how our posts should look like. create a file called post.model.ts with the following content:\u00a0<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"post.model.ts\">export interface Post {\r\n  title: string;\r\n  content: string;\r\n}<\/pre>\n<p><span class=\"token p\">We&#8217;ll add the likes later. Next let&#8217;s build a form in the manage-posts-component to create our posts.<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"manage-posts.component.html\">&lt;form [formGroup]=\"postForm\" (ngSubmit)=\"save()\"&gt;\r\n  &lt;input type=\"text\" placeholder=\"your post title\" formControlName=\"title\"&gt;\r\n  &lt;textarea placeholder=\"your post title\" formControlName=\"content\"&gt;\r\n&lt;\/form&gt;<\/pre>\n<pre class=\"lang:default decode:true\" title=\"manage-posts.component.ts\">postForm: FormGroup;\r\n\r\nconstructor(private postService: PostService){ }\r\n\r\nngOnInit() {\r\n  this.postForm = new FormGroup({\r\n    title: new FormControl('', Validators.required),\r\n    content: new FormControl('', Validators.required)\r\n  });\r\n}\r\n\r\nsave() {\r\n  const title = this.postForm.get('title').value;\r\n  const content = this.postForm.get('content').value;\r\n  \/* TODO: save data to firestore *\/\r\n}<\/pre>\n<p><span class=\"token p\">The only thing left to set up is our post service that communicates with Firestore. But before that let&#8217;s first talk about how Firestore structures your data.<\/span><\/p>\n<h2>Firestore Data Structure<\/h2>\n<p><span class=\"token p\">Firestore data is stored within a <strong><span class=\"token em\">document<\/span><\/strong>. A document is very similar to a JSON Object &#8211; it contains fields which map to values. It has all the regular JSON data types like strings, numbers, booleans etc. plus some <a href=\"https:\/\/firebase.google.com\/docs\/firestore\/manage-data\/data-types\">additional ones<\/a>.<\/span> <span class=\"token p\">Then there&#8217;s also <strong><span class=\"token em\">collections<\/span><\/strong>.<\/span> Collections are basically just lists of documents that organize your documents and group them together.<span class=\"token li\"><span class=\"token md md-li\">\u00a0The most important two rules to keep in mind about documents and collections are these:<\/span><\/span><\/p>\n<ul>\n<li><span class=\"token li\">every document has to be contained within a collection <\/span><\/li>\n<li><span class=\"token li\">You don&#8217;t need to manage collections\u00a0\u2014 Collections are automatically created when you add the first document to them and deleted when they&#8217;re empty<\/span><\/li>\n<\/ul>\n<p><span class=\"token p\">So let&#8217;s get to structuring the data in our blog app. We want have a bunch of posts, so we&#8217;ll use a collection called &#8216;posts&#8217; in which we&#8217;ll put our post-documents. So let&#8217;s get to implementing our post service:<\/span><\/p>\n<p><span class=\"token p\">first we need to pass AngularFirestore to the constructor:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">constructor(private afs: AngularFirestore) { }<\/pre>\n<p>(Don&#8217;t forget to import AngularFirestore into your module!)<\/p>\n<p><span class=\"token p\">Then we need to create a path name for to our collection:<\/span><\/p>\n<pre class=\"lang:js decode:true\" title=\"post.service.ts\">readonly path = 'posts';<\/pre>\n<p>With those two in place, we can access our Firestore collections and documents by writing:<\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">afs.collection&lt;Post&gt;(this.path); \r\nafs.doc&lt;Post&gt;(`${this.path}\/${id}`); \r\n<\/pre>\n<p><span class=\"token p\">Note that the\u00a0document can then be accessed at the path\u00a0\u00a0<code>'posts\/:postid'<\/code>\u00a0. Later we will get to how t o access the document ids.\u00a0<\/span><span class=\"token p\">These collections and documents contain all the methods that we need to implement our CRUD operations, so let&#8217;s get started!<\/span><\/p>\n<h2>1. Saving Data<\/h2>\n<p><span class=\"token p\">To save data to Firestore, we pass the data we want to store to the add method on the collection:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">add(data: Post): Promise&lt;DocumentReference&gt; {\r\n  return this.afs.collection&lt;Post&gt;(this.path).add(data);\r\n}<\/pre>\n<p><span class=\"token p\">We can then call our newly created add method within save:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"manage-posts.component.ts\">save() {\r\n  const title = this.postForm.get('title').value;\r\n  const content = this.postForm.get('content').value;\r\n  this.postService.add({title, content});\r\n}<\/pre>\n<p>And that&#8217;s it! Our data can now be stored in Cloud Firestore. One thing to note here is<span class=\"token p\">\u00a0that the add method creates a new document with an id generated by Cloud Firestore itself.<\/span>\u00a0 If you want to name the path yourself, you can do so by setting the document manually:<\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">set(id: string, data: Post): Promise&lt;DocumentReference&gt; {\r\n  return this.afs.doc&lt;Post&gt;(`${this.path}\/${id}`).set(data);\r\n}<\/pre>\n<h2>2. Reading Data<\/h2>\n<p><span class=\"token p\">Now that we have saved the data, we also want to read it. One really nice thing about angularfire2 is is that it gives you the ability to stream your data and get it directly as an Observable. So let&#8217;s go through the different ways to get your data with angularfire2:<\/span><\/p>\n<p><span class=\"token p\">The simplest way to get your data is by calling the <code>valueChanges()<\/code> method, which returns you an observable stream of your requested data, so you can easily react on data updates in the backend. In code it looks like this:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">getCollection$(): Observable&lt;Post[]&gt;{\r\n  return this.afs.collection&lt;Post&gt;(this.path).valueChanges();\r\n}<\/pre>\n<p><span class=\"token p\">Pretty straightforward, right? The drawback is that you only get the posts themselves without any metadata like their id, so you can&#8217;t actually make any updates to the documents themselves.\u00a0<code>ValueChanges()<\/code><\/span>\u00a0\u00a0is good if you just want to display your data, but most of the time you&#8217;ll need something more sophisticated.<\/p>\n<p><span class=\"token p\">If you want to update or delete your data after getting it, you&#8217;ll need to use\u00a0<code>snapshotChanges()<\/code>\u00a0.\u00a0<\/span><span class=\"token p\">This method returns an Observable of type <code>DocumentChangeAction[]<\/code>\u00a0, which contains a lot of interesting metadata such as whether the data change was due to an add,\u00a0 remove or modify event. Moreover, it contains a <code>DocumentSnapshot<\/code>\u00a0, which includes \u2014 among other information\u00a0\u2014 the post&#8217;s data and ids<\/span>. For now we&#8217;re only interested in the latter, so we&#8217;ll use Rx&#8217;s map-operator to convert the <code>DocumentChangeAction[]<\/code>\u00a0\u00a0to a\u00a0<code>Post[] + id<\/code>:<\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">getCollection$(): Observable&lt;Post[]&gt; {\r\n  return this.afs.collection&lt;Post&gt;()\r\n    .snapshotChanges().map(actions =&gt; {\r\n      return actions.map(a =&gt; {\r\n        const data = a.payload.doc.data() as Post;\r\n        const id = a.payload.doc.id;\r\n        return { id, ...data };\r\n      });\r\n    });\r\n}<\/pre>\n<p><span class=\"token p\">Also let&#8217;s change our post model to include an optional id:<\/span><\/p>\n<pre class=\"lang:default decode:true \" title=\"post.model.ts\">export interface Post {\r\n    title: string;\r\n    content: string;\r\n    id?: string;\r\n}<\/pre>\n<p><span class=\"token p\">Now we can get to displaying our data our our view-post-component. First get the data from our post service:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"view-posts.component.ts\">posts$: Observable&lt;Post[]&gt;;\r\n\r\nconstructor(private postService: PostService) { }\r\n\r\nngOnInit() {\r\n  this.posts$ = this.postService.getCollection$();\r\n}<\/pre>\n<p><span class=\"token p\">and then loop over it in our html:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"view-posts.component.html\">&lt;div class=\"card\" *ngFor=\"let post of posts$ | async\"&gt;\r\n  &lt;div class=\"card-header\"&gt;\r\n    &lt;div class=\"card-title h5\"&gt;{{post.title}}&lt;\/div&gt;\r\n  &lt;\/div&gt;\r\n  &lt;div class=\"card-body\"&gt;\r\n    &lt;p&gt;{{post.content}}&lt;\/p&gt;\r\n  &lt;\/div&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>(Sidenote: I&#8217;m using a little css framework for my styles called <a href=\"https:\/\/picturepan2.github.io\/spectre\/\">spectre.css<\/a>\u00a0for my styles, hence the style classes, in case you were wondering.)<\/p>\n<h2>3. Updating Data<\/h2>\n<p><span class=\"token p\">Now that we can display our posts and reference their corresponding docs by their ids, we can easily build in the like-functionality. First let\u2019s create an update method in our Post-Service.<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">update(id: string, data: Partial&lt;Post&gt;): Promise&lt;void&gt; {\r\n  return this.afs.doc&lt;Post&gt;(`${this.path}\/${id}`).update(data);\r\n}<\/pre>\n<p><span class=\"token p\">Note that the update method only requires a Partial of Post, which allows us to only update a single field of the document, which is pretty handy.<\/span>\u00a0<span class=\"token p\">After that is done we can extend our Post model to contain a like-field:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"post.model.ts\">export interface Post {\r\n  title: string;\r\n  content: string;\r\n  likes: number;\r\n  id?: string;\r\n}<\/pre>\n<p>Then we\u2019ll fix the call of our add method so it initializes all posts with zero likes.<\/p>\n<pre class=\"lang:default decode:true\" title=\"manage-posts.component.ts\">this.postService.add({ title, content, likes: 0 });<\/pre>\n<p><span class=\"token p\">And add a like method that increases a post\u2019s like counter by one.<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"view-posts.component.ts\">like(post: Post) {\r\n  this.postService.update(post.id, {likes: post.likes + 1});\r\n}<\/pre>\n<p><span class=\"token p\">Lastly we\u2019ll add the like button to our html:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"view-posts.component.ts\">&lt;div class=\"card\" *ngFor=\"let post of posts$ | async\"&gt;\r\n  ...\r\n  &lt;div class=\"card-footer\"&gt;\r\n    &lt;button class=\"btn btn-primary\" (click)=\"like(post)\"&gt;Like&lt;\/button&gt;\r\n    &lt;span&gt;{{post.likes}} Likes&lt;\/span&gt;\r\n  &lt;\/div&gt;\r\n&lt;\/div&gt;<\/pre>\n<h2>4. Deleting Data<\/h2>\n<p><span class=\"token p\">Finally we want to be able to delete our posts. Implementing that will be just as easy as updating the data. First let&#8217;s write our deletion method into our post-service:<\/span><\/p>\n<pre class=\"lang:default decode:true\" title=\"post.service.ts\">remove(id: string): Promise&lt;void&gt; {\r\n  return this.afs.doc&lt;Post&gt;(`${this.path}\/${id}`).delete();\r\n}<\/pre>\n<p><span class=\"token p\">Note that we want to avoid calling the method \u201cdelete\u201d because it is a reserved keyword in JavaScript that shouldn\u2019t be used for identifiers (<a href=\"http:\/\/es5.github.io\/#x7.6.1.1\"><span class=\"token link\"><span class=\"token md md-underlined-text\">see here<\/span><\/span><\/a>)<\/span>.<\/p>\n<p>Just as with update, we need to add the remove method to our component:<\/p>\n<pre class=\"lang:default decode:true\" title=\"manage-posts.component.ts\">remove(id: string) {\r\n  this.postService.remove(id);\r\n}<\/pre>\n<p>And for the final step, we want to display our posts in a table and give each row a delete button to remove the corresponding post. Here&#8217;s how that looks like in code:<\/p>\n<pre class=\"lang:default decode:true\" title=\"manage-posts.component.html\">&lt;table class=\"table table-striped table-hover\"&gt;\r\n  &lt;thead&gt;\r\n  &lt;tr&gt;\r\n    &lt;th&gt;name&lt;\/th&gt;\r\n    &lt;th&gt;likes&lt;\/th&gt;\r\n    &lt;th&gt;delete&lt;\/th&gt;\r\n  &lt;\/tr&gt;\r\n  &lt;\/thead&gt;\r\n  &lt;tbody&gt;\r\n  &lt;tr *ngFor=\"let post of posts$ | async\"&gt;\r\n    &lt;td&gt;{{post.title}}&lt;\/td&gt;\r\n    &lt;td&gt;{{post.likes}}&lt;\/td&gt;\r\n    &lt;td&gt;\r\n      &lt;button class=\"btn\" (click)=\"remove(post.id)\"&gt;\r\n        &lt;i class=\"icon icon-cross\"&gt;&lt;\/i&gt;\r\n      &lt;\/button&gt;\r\n    &lt;\/td&gt;\r\n  &lt;\/tr&gt;\r\n  &lt;\/tbody&gt;\r\n&lt;\/table&gt;<\/pre>\n<p>And that&#8217;s it! We sucessfully implemented CRUD operations with Firestore. Again, you can check out the source code on <a href=\"https:\/\/github.com\/biowaffeln\/blog-app\">github<\/a>.<\/p>\n<h1>Conclusion<\/h1>\n<p>As we have seen in this tutorial, it&#8217;s really fast and easy to get started with Cloud Firestore. Moreover, the AngularFire2 wrapper makes it a great fit for use in Angular projects.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few weeks ago, Google has released its new solution for building scalable cloud databases\u00a0\u2014 the Cloud Firestore. It has some nice improvements in comparison to their previous database (which used to be called Firebase but is now referred to as &#8216;Realtime Database&#8217;), like better data structuring and a more powerful querying API. In this [&#8230;]<br \/><a class=\"meta-big\" href=\"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/\"> READ MORE<\/a><\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[73,2,60],"tags":[74,97,61,75],"class_list":["post-1312","post","type-post","status-publish","format-standard","hentry","category-angular","category-javascript","category-typescript","tag-angular-2","tag-firestore","tag-javascript","tag-typescript"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Getting started with Firestore and AngularFire2 - Web Development Blog<\/title>\n<meta name=\"description\" content=\"A tutorial for getting started with google&#039;s new noSQL Database Cloud Firestore and Angular using the official AngularFire2 library.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Getting started with Firestore and AngularFire2 - Web Development Blog\" \/>\n<meta property=\"og:description\" content=\"A tutorial for getting started with google&#039;s new noSQL Database Cloud Firestore and Angular using the official AngularFire2 library.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Development tips and tricks - theCodeCampus Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-13T14:11:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-03-14T13:29:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg\" \/>\n<meta name=\"author\" content=\"theCodeCampus\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"theCodeCampus\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/\"},\"author\":{\"name\":\"theCodeCampus\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/person\\\/276bbda2f8da73154f22fb652201cfbc\"},\"headline\":\"Getting started with Firestore and AngularFire2\",\"datePublished\":\"2017-11-13T14:11:27+00:00\",\"dateModified\":\"2022-03-14T13:29:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/\"},\"wordCount\":1495,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/maxresdefault-1024x576.jpg\",\"keywords\":[\"Angular 2\",\"Firestore\",\"JavaScript\",\"TypeScript\"],\"articleSection\":[\"Angular\",\"JavaScript\",\"TypeScript\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/\",\"name\":\"Getting started with Firestore and AngularFire2 - Web Development Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/maxresdefault-1024x576.jpg\",\"datePublished\":\"2017-11-13T14:11:27+00:00\",\"dateModified\":\"2022-03-14T13:29:58+00:00\",\"description\":\"A tutorial for getting started with google's new noSQL Database Cloud Firestore and Angular using the official AngularFire2 library.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#primaryimage\",\"url\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/maxresdefault-1024x576.jpg\",\"contentUrl\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/maxresdefault-1024x576.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/getting-started-firestore-angularfire2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Getting started with Firestore and AngularFire2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/\",\"name\":\"Web Development tips and tricks - theCodeCampus Blog\",\"description\":\"Tips, tricks, and experiences about developing web and mobile applications with Angular, TypeScript, and Testing.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#organization\",\"name\":\"theCodeCampus\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/TCC-Logo-Bildmarke-quadratisch.jpg\",\"contentUrl\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/TCC-Logo-Bildmarke-quadratisch.jpg\",\"width\":156,\"height\":156,\"caption\":\"theCodeCampus\"},\"image\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/person\\\/276bbda2f8da73154f22fb652201cfbc\",\"name\":\"theCodeCampus\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/TCC-Logo-Bildmarke-quadratisch-96x96.jpg\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/TCC-Logo-Bildmarke-quadratisch-96x96.jpg\",\"contentUrl\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/TCC-Logo-Bildmarke-quadratisch-96x96.jpg\",\"caption\":\"theCodeCampus\"},\"description\":\"Our knowledge is not simply gained through reading - it is trained, tested and constantly being expanded. Because first and foremost, we are all developers at W11K. The know-how that we acquire here as developers, consultants and information architects flows immediately into our training courses and articles for theCodeCampus.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/showcase\\\/thecodecampus\\\/\"],\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/author\\\/admin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Getting started with Firestore and AngularFire2 - Web Development Blog","description":"A tutorial for getting started with google's new noSQL Database Cloud Firestore and Angular using the official AngularFire2 library.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/","og_locale":"en_US","og_type":"article","og_title":"Getting started with Firestore and AngularFire2 - Web Development Blog","og_description":"A tutorial for getting started with google's new noSQL Database Cloud Firestore and Angular using the official AngularFire2 library.","og_url":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/","og_site_name":"Web Development tips and tricks - theCodeCampus Blog","article_published_time":"2017-11-13T14:11:27+00:00","article_modified_time":"2022-03-14T13:29:58+00:00","og_image":[{"url":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg","type":"","width":"","height":""}],"author":"theCodeCampus","twitter_card":"summary_large_image","twitter_misc":{"Written by":"theCodeCampus","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#article","isPartOf":{"@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/"},"author":{"name":"theCodeCampus","@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/person\/276bbda2f8da73154f22fb652201cfbc"},"headline":"Getting started with Firestore and AngularFire2","datePublished":"2017-11-13T14:11:27+00:00","dateModified":"2022-03-14T13:29:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/"},"wordCount":1495,"commentCount":1,"publisher":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#organization"},"image":{"@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg","keywords":["Angular 2","Firestore","JavaScript","TypeScript"],"articleSection":["Angular","JavaScript","TypeScript"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/","url":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/","name":"Getting started with Firestore and AngularFire2 - Web Development Blog","isPartOf":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#primaryimage"},"image":{"@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg","datePublished":"2017-11-13T14:11:27+00:00","dateModified":"2022-03-14T13:29:58+00:00","description":"A tutorial for getting started with google's new noSQL Database Cloud Firestore and Angular using the official AngularFire2 library.","breadcrumb":{"@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#primaryimage","url":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg","contentUrl":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/11\/maxresdefault-1024x576.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.thecodecampus.de\/blog\/getting-started-firestore-angularfire2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.thecodecampus.de\/blog\/"},{"@type":"ListItem","position":2,"name":"Getting started with Firestore and AngularFire2"}]},{"@type":"WebSite","@id":"https:\/\/www.thecodecampus.de\/blog\/#website","url":"https:\/\/www.thecodecampus.de\/blog\/","name":"Web Development tips and tricks - theCodeCampus Blog","description":"Tips, tricks, and experiences about developing web and mobile applications with Angular, TypeScript, and Testing.","publisher":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.thecodecampus.de\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.thecodecampus.de\/blog\/#organization","name":"theCodeCampus","url":"https:\/\/www.thecodecampus.de\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/01\/TCC-Logo-Bildmarke-quadratisch.jpg","contentUrl":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/01\/TCC-Logo-Bildmarke-quadratisch.jpg","width":156,"height":156,"caption":"theCodeCampus"},"image":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/person\/276bbda2f8da73154f22fb652201cfbc","name":"theCodeCampus","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/01\/TCC-Logo-Bildmarke-quadratisch-96x96.jpg","url":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/01\/TCC-Logo-Bildmarke-quadratisch-96x96.jpg","contentUrl":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/01\/TCC-Logo-Bildmarke-quadratisch-96x96.jpg","caption":"theCodeCampus"},"description":"Our knowledge is not simply gained through reading - it is trained, tested and constantly being expanded. Because first and foremost, we are all developers at W11K. The know-how that we acquire here as developers, consultants and information architects flows immediately into our training courses and articles for theCodeCampus.","sameAs":["https:\/\/www.linkedin.com\/showcase\/thecodecampus\/"],"url":"https:\/\/www.thecodecampus.de\/blog\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts\/1312","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/comments?post=1312"}],"version-history":[{"count":52,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts\/1312\/revisions"}],"predecessor-version":[{"id":2594,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts\/1312\/revisions\/2594"}],"wp:attachment":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/media?parent=1312"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/categories?post=1312"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/tags?post=1312"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}