Golang / Go Crash Course 02 | Connecting our REST API with Firebase Firestore Database

Golang / Go Crash Course 02 | Connecting our REST API with Firebase Firestore Database


what’s going on guys, in this video I’m
going to connect our Golang API with a Firestore database replacing the
array that we are currently using to store the data. Firestore is a NoSQL
database from Google Firebase… and if you have a WordPress website or if you’re
planning to have one checkout Elementor Elementor is the best page builder for
WordPress there is a link in the description below this video. Remember to
share, like and subscribe to the channel 🙂 and let’s get started! Okay first let’s
create our Firestore database and we have to go to console.firebase.google.com so and here we go to create a project and we assign a name to
it “pragmatic-reviews”… we click on continue I’m going to disable analytics on the project I’m
going to click on create project and this is going to take a while…. okay the
project is ready so we click on continue and here we need to go to Database and
here where it says Cloud Firestore we click on create database we are going to
start in production mode click on next done I’m just setting the default
location in this case is US Central but you can select another region or another
location for the deployment of the database okay now that the database is
ready we can start a collection for example we can assign a name to it in
our case is going to be posts and this can be the structure that we are going
to use we gonna have an ID, there is going to be a number and we’re gonna have a title
for our posts that’s gonna be a string and we’re gonna have a text that is
gonna be an string well and we are going to use the document identifier
generated by the Firestore Engine and we can add some values here one,
“Title 1” and “Text 1” for example and we can save this and we have our first
document created… remember that Firebase is a NoSQL database where basically
a database is a collection and a collection has multiple documents the
next step is going to be exporting a JSON file (with the private key to access…) so we can access the database
this file is going to include the private key we need to go to project
overview and click here on project settings then we have to go to service
accounts and here we need to click on generate new private key and here click
on generate key and this is going to download a JSON file let’s open it and
it’s basically going to include a project identifier we’re going to need
to use this identifier in our code to access this database we have a project
identifier a private key ID, the private key and this is this one and some other
details ok and once we have the JSON file one of the recommended options to
set up the access to the Firestore database and the Firebase services is
creating this environment variable GOOGLE_APPLICATION_CREDENTIALS and this variable needs to point to this JSON file that we just
downloaded this will allow us to access the firebase resources in our case we
are going to access the Firestore database….. In the first video of the
series we’ve been working on an initial version of our API using Mux and we
were basically storing these post elements which structure is defined
here within this posts array so what we are going to do now is we are going to
remove actually this array and we’re going to
create a repository that is going to access our Firestore database, first we are
going to create a new file we’re going to call this post-repo.go and here we are going to create a different package let’s call it
repository and I’m going to move this within a folder repository… this
repository is going to have an interface that is going to be… let’s call it PostRepository and it’s going to have two methods it’s gonna have a save
method that is going to receive a post actually it’s going to receive a
reference to the post and this is pretty common on Golang in order to handle errors is
going to return in this case we’re going to return the object or the reference to
the element and an error in case we get any errors we’re going to
return an error so this is the mechanism that Golang uses to handle errors so we
always need to check if this value returned by the function is nil or
not… okay and the other method is going to be a FindAll() that is going to return
either a collection of posts or an array of posts or an error so
that’s gonna be our interface and I’ve already created here in the routes file
this struct… what I’m going to do is I’m going to move this to an external file
so I can import this structure from this routes file and also from this
repository so I’m going to create a new folder I’m going to call it entity and here I’m going to create a new file I’m going to call it post.go
and I’m going to cut this and I’m going to paste it here at first I need to find
a package that’s going to be entity let’s save this ok and now from the
repository I’m going to import that entity import and it’s going to be “../entity” from here I can access this type by doing entity.Post and the same here entity.Post and entity.Post… and now to
implement this interface we need to create an struct
I’m going to call it repo with a constructor to create a new
instance this is gonna be NewPostRepository that is going to be the name of the
function and it’s going to return this struct that is going to
implement the PostRepository interface so the (return) type of this function is going to be PostRepository and here we’re going to return a reference to the repo struct
like this okay and now this is going to throw an error because we are not
implementing any of these methods that we declare as part of the
interface so we have to implement those methods as part of this struct okay so
the first function I’m going to grab this from here it’s going to be Save()
and the way that we have to make that struct to implement this method is like
this we need to add it here we can add a reference like this okay we’re going to
start working with our Firestore database and in order to do that I need
to import a library I need to install a library and then import it… so I
need to run go get and the location of these dependencies cloud.google.com/go/firestore and it’s going to download the
dependency and I need to import it here I’m going to copy from here and I’m
going to add it here okay the first thing that we need to do is we need to
access the context of the application and we do that by doing this… we create a
variable and we assign context.Background() and this should import the
context dependency for us in this background method that’s actually a method
is going to give us an empty context okay
and this context is a parameter that we need to pass when we create a new Firestore client so let’s create that client we can do it like this we need to pass the
client and an error remember that this is the most common
way that Golang uses to handle errors basically you call a method and that
method returns the object that you expect and also an error and then you need to
check if the error is nil or not okay… here we need to use firestore.NewClient(…) and here we pass the empty context that we created on line 22 (ctx)
and we need to pass the project ID so I’m going to create a couple of
constants here Const and one of them is going to be the
project ID that in our case is “pragmatic-reviews” okay so we pass the
context and then the constant that we just created
that is projectID like this okay and here I’m going to check if we get any errors I’m going to log a message “Failed to
create a firestore client…” and we can log the error like this “%v, err” and here we return
nil as the result and we “propagate” the error here… okay now assuming
that we didn’t get an error we can add a new element to the collection like
this client.Collection(…) and we need to pass the collection name that in our case let’s go back to the
firebase console and if we go to that database… is our collection is “posts” so we
need to use that one and I’m going to create a new constant right we need to
add the type here actually string and it’s gonna be string as well… now that we
have access to the collection to the posts collection we
can call the add method and again we need to pass the context here again and
here what we are going to use is a map a map is a collection of key-value pairs so
a map in Golang you need to declare it like this map in this case the keys are
gonna be strings and if we go back to the Firebase console we can see that
this is going to be the identifier and this is going to be the value of the map
he’s gonna have an ID, a text and a title this is the type of the key of the map
and after that we need to declare the type of the value for each entry in this
case is gonna be an interface and that interface is going to include those
three attributes an identifier and here we assign the identifier of the post so
this is post.ID and after that we have the title and here again we assign
the title of the post and after that I forgot to add a comma here and here and
after that we need to add text post.Text… like that okay and again we need
to handle (…let me check…) okay I guess yes the entity here okay now we should be
fine yes and as usual here we are going to receive the values that we expect and
also the error so we need to declare we need to assign those values and in this
case we’re going to receive three elements if we go here to the Add method here we
can see that we get a DocumentRef, a WriteResult and the error and in our
case we are not going to use any of these so the way that
golang provides to have variables that we are not going to use we can use
underscore for that this is to declare blank variables or variables that we are
not going to use so we use underscore for the first one that is actually this
DocumentRef value.. the other one for the this one for the WriteResult value and
then the error like that okay and as usual I’m going to check if I get any
errors and I’m going to copy this and I’m going
to change the message that in this case is going to be “Failed adding a new post…”
and then the details of the error and one thing that I need to add here is I need
to close the client and one way that Golang provides to defer the execution of a
specific line in our code is the defer defer keyword and here we can say client.Close() for example and this is going to close the firestore client
once the function finishes so once this function returns a value the client is
going to close so this line is going to be executed after this function returns
a value and now what I need to do is I need to return the post and nil this is
the case where we didn’t get any errors so that’s it for the Save() function… we
still need to implement the FindAll() method here we get that message we get that
with an error that says that we are not implementing the FindAll() method so I’m
going to do that I’m going to copy this from here so func and here we need to
pass again the reference to the struct that is the repo okay here again we need to create a
context we need to create a client maybe we can move this to a function and we
need to return yes the context we need to return the client but yeah that’s
going to be better from the design perspective and to avoid repeating code
but for now I’m going to copy and paste just to move on (don’t do this at home 🙂 ) okay let me see…here again we need to close the client once the function finishes and I’m going
to create a variable here that’s going to be an array of posts and
I’m going to iterate the posts document from firestore and I’m going to add
those elements within this array so this is going to be an array of posts
this is entity.Post and here I’m going to get an iterator and the way I
have to get the iterator for the collection is client.Collection(…) we need to pass the collection name that is one of our constants it’s actually this one and
here I need to use the Documents element as we can see here Documents returns an
iterator over the queries resulting documents so we call Documents and we
pass the context again here okay and now that we have this iterator we need to add a
“for sentence” and within this loop we need to access each element by using the
next() method… iterator.Next() and here we assign the value that we expect and
the error and here we handle the error if there is an error… we do something
like this and here we can say “Failed to
iterate the list of posts…” and we’ll return nil as the result and then we “propagate”
the error we “throw” the error okay if we didn’t get any errors we create the post we need to use the Post struct like this
and we need to assign the values but by getting those values from the document
that is the value that we get here when we call the Next() method of the iterator
so here’s our ID and this is doc.Data() and this is an array so here we
pass the name of the attribute as the index of this array and it’s going to be
an int like that and the same for the title in this case is gonna be a string and the
same for the text… great and now we add this post to the posts collection…we use append(…) for that…..”posts, post” the period (.) and the type here (int) is a type assertion and in case that for example this identifier is a string this is going to
throw an error the same here if we get a number as a title it’s going to also
throw an error okay and here we need to return the array and nil when we reach
this point is because we didn’t get any errors okay and we should not have any
more errors here yes now the struct is implementing both
methods that we defined up here on this interface okay and now that our repo is
ready we are going to replace this posts array from here and we are going to use
that repo so we are going to import the repository this is the package
and here we’re going to declare that repository let’s call it repo and the
type of this repo is going to be repository.PostRepository that
is actually this interface that we declared here and this is gonna be and
here we need to call the NewPostRepository() function repository and this
also within this package so I need to add the package at the beginning okay
and now we have access to this function great okay and this init function we don’t need it… so I’m going to remove it and now I’m going to replace this posts (array) so
actually these posts are going to come from the database so I need to use posts
and error and here I need to use the repo repo.FindAll() this is the method and here we need to actually handle that error if there are any
errors we need to return something like “Error getting the posts…” and after that
if we don’t get any errors I’m going to remove this and I’m going to return the
HTTP 200 and I’m going to use json.NewEncoder(…) and I’m going to pass the HTTP response as a
parameter and I’m going to encode the array so here and that’s it for the
GetPosts() method okay moving on to the AddPost() method I need to actually
import the entity this one so I’m going to do that here I need to import the
entity package so here this is not Post is entity.Post like that and here I
don’t have this array anymore so what I’m going to do to generate the
identifier of the post that’s actually ID like that… I’m going to assign a random
number so I’m going to use a library to generate that random number that is
rand.Int….. and this is the library that I’m using now to generate
that random number so I guess that let’s check this function returns an int and
an error so yeah we need to have the error here and what’s the problem… type int….. it looks like the types are different so okay I’m going to
use a different library that is within this package: “math/rand” and let’s
see if I can use this method and I guess yeah that works… okay and this returns an
int and here this is an int so we’re good and I don’t need to add this post
to the array… I need to replace this by calling the save method from the repo so I need
to pass the post here and pass actually the referenced post and here what I’m
going to do is something similar to this json.NewEncoder(…) and call response
and I’m going to encode the post like that so let’s try this… so first let’s
check what we have in the database we only have one element there’s this one
ID:1, text:”Text 1″ and title: “Title 1″ and let’s run the GET operation so we
should get…. okay let’s see what’s going on…we have an error…..”..interface conversion is int64…” okay okay this is the type that we need to use to match with this with a
number type for the identifier (from the Firestore document) okay so let’s use that so I need to
change this type here int64 I need to go to the repo and I need to replace that
type here int64 and here I need to use another function let’s see this one int63() returns an int64 type so I’m going to use that one to generate our random
identifier and now let’s run this…. I’m going to remove all the elements from the
database ……and this one as well okay now we don’t have any documents
so I’m going to create the first one it’s gonna be “Title 1” and “Text 1” (submitting the request…) if
we go to the database yes we have this random identifier “Text 1” and “Title 1”
and if we execute the GET operation we get that element I’m going to create a
new one let’s say “Title 333” and “Text 333” we send this (submitting again) okay we go to the database yes… we have that information there and if we execute the GET operation yes we get
both elements okay that’s pretty much all I have for today… in the next video
I’m going to refactor this code because here we have like a mix between things
that are part of a controller typically like sending a content type in the
header and it’s mixed with some logic so I am going to implement a “Clean
Architecture” (from Uncle Bob) so we’re gonna have a better separation of concerns… so thank
you guys for watching and I see you in the next video, take care! bye! 🙂

1 thought on “Golang / Go Crash Course 02 | Connecting our REST API with Firebase Firestore Database”

  1. ➥➥ Learn even more! ➥➥
    Golang Crash Course ➥ http://bit.ly/39ZH8dy
    Vue.js Crash Course ➥ http://bit.ly/37mCaFM
    Vuetify.js Crash Course ➥ http://bit.ly/2sArggU
    Nuxt.js Crash Course ➥ http://bit.ly/37kQiPG
    TypeScript Crash Course ➥ http://bit.ly/37lJEsH
    NestJS Crash Course ➥ http://bit.ly/2QevL9X
    Automate.io Crash Course ➥ http://bit.ly/2SRGlph
    Zapier Crash Course ➥ http://bit.ly/37q1BGt
    SEO Crash Course ➥ http://bit.ly/2QbIhqy
    WordPress Crash Course ➥ http://bit.ly/2ZBZRr5

    ➥ Get your FREE Golang Cheat Sheet here: https://www.pragmaticreviews.com/

    If I have helped you in any way please consider becoming a patron for just $1/month ➥ https://www.patreon.com/pragmatic
    Try Linode Hosting Service Here ➥ https://pragmaticreviews.com/linode
    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *