Golang: Firebase Realtime Database CRUD operations

Update data anywhere, obtain the latest data anywhere on the fly…
Oct 12 2022 · 3 min read

Introduction 

Have you ever faced a situation where you want the latest data on multiple places the very next moment it gets updated?

Consider a scenario: you’re shopping from an e-commerce website and your friend is also using your account to do some shopping for her using a mobile application. At that time, the shopping cart needs to be updated with the total items and prices considering both of your preferences.

Now, consider you’re developing a quiz application that has 2 interfaces web and mobile app, and you need to maintain the actual score of the user at the same time.

It’s terrible to think of your database(MySQL/NoSQL) for bringing the latest data and updating the cart on both the platform(website and mobile app), as it will continuously trigger the server for the latest update.

The databases will not give updated data without doing an API(HTTP) call.

There comes real-time interaction in the picture.

Give me a favor!

If you’re thinking that WebSocket is the way to go in such a situation, you’re completely right. But we don't need to manage WebSocket by ourselves, firebase does it on our behalf!

Firebase's real-time database saves the data and also informs all the clients that are configured to receive a real-time update, as and when the data gets updated.

Prerequisites

The Golang packages for firebase

  • firebase.google.com/go/v4
  • firebase.google.com/go/v4/db

Configure Firebase real-time database

If you have not set firebase real-time database yet, follow Create firebase real-time database instructions and create one.

P.S: If you’re using it for testing, you can choose Test mode but it will also allow anyone to access it, hence choose Locked mode instead.

If you configure the database in us-central1 region
the database URL will be in a format like https://<your-project-name>.firebaseio.com .

If it’s inside other regions then it should look like https://<project-name>.<region>.firebasedatabase.app .

Setup database rules

By default, if we don’t set any rules it will allow anyone to interact with it. To overcome such exposure, we need to set read and write rules to false.

However, these rules will still allow authenticated users to access the database.
Find more about Setting firebase database rules.

Generate and configure the service account key

Google service account key is the way to authorize users for accessing our database. So, generate one if you haven’t already and add it to the project.

Generate and configure the service account key


A service account key looks like this,

{
  "type": "service_account",
  "project_id": "fir-realtime-db-demo-xxxxx",
  "private_key_id": "9b40ce1e420b06c04b4c8e543bebbd43cd731a22",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIxxxxxxxxxxxxxxw0BAQEFAASCBKgwggSkAgEAAoIBAQDllkqdmGaEonsN\nSsACNopfNG92Ak548KEqDPzw+xxxxxxxxyRMj97Zzz50dY2cUXHmvCwFQhq3KRh7\n9VAFeNflKSmlhw5+ch8eiI1hfqiIpS6Vl+TwVcOSY7SJZaWP9WjCo1inKL6Ur829\nTrKw/54i7TAocaund54ZEFnlhbk0UTSdRwtfzUny5A35EvPXlJazjvkhB5VuB/+F\nxxxxx/ffFcbeqMBwi1Vb9hi1zT2BXV22NUmBxZyp6VQwVfl34XTEZBAutqnVinqz\nuCtkxo+RiZY5yG4csOIkVqsFJ7NYnZE6iwYc1cFtp5IKmP7TZEchyje4crtJUZTf\nC3jyAbrnAgMBAAECggEAXxDBaspNQQSKkXFvWjs9RrjOon3IApoZEfF410rPozAp\nXcbAZBd6vpPrF4wJjD3JPTKTw8WgjFEu+z0T2oA0XYaS4SCwZrlYm2sNp94raRGE\n3ZqcyMuqhLZWbkIxsQ98RoQe1HCxoZ2+QnIQ2euujmXKeCTBYEHOrDAyGTErBDcH\nC98ikFKq/pd6B8ZJ9PbCYIth8KgxQBk+TsY2zEMZN0zM+7fDuTEr914OstT6t6Bb\nAle5aXTYxZNHsTY2mR/4Zo88k4JazEZzQ26BHmi5vdcez6uJuqwoRru0jWAoneTi\nrsUKhajwuKK2nwn+t5m4PABy4hU2VlrJhwPr0o0diQKBgQD42EIP9f9d1JC4OJ3b\nJsQdytTEzcKziF12VAj4rPjGbnWMoIc/6UHO3DNSJyrdZUjakZnaXBnJZkljXsE4\nhJck2s5U80elXH2eWw4qNzLuOxeHlNrZs6HzTzoG0ZGEC2ALvGy5USUsO+a3idsO\nEnklJTEwFdBtqx4MEXPsiyQptQKBgQDsMEcnn9QZLi3SMC+mEeOQDmq7Jm4KygL2\neHVDrq4P4X1Pn7IYqi7iJDxWKBzgCutxFwQOJiZdoedhAg1HhIZckT4VFvkwUHlS\nxu0l21OTFmu/2OUANNDoS8cJwOx+NDe23xbOk6PrVjD4OJtSRc5CDd+reSm1lwVq\nIHizueHDqwKBgD7RWNvunahyIJZgtHi+MIPU0CFeT+hCZFWaoSklgSeWetYlL/9S\nQuqVa98xRADfsKR8XPpihZ/x0lTjdqNt1TnYgn2vbEayMoPnOIwvowvAnw/648RR\nNHDXby6JeNJ8jKJpzoh5k4i3Fmb+xe2nfC2EVgZte1A0AkHJphnwhhCBAoGBAIgl\n5D5xIYBKYFtzL2RZl4Xo6ZlsM67AeCi/k0kqnmfFIckOU0logJIXNTis8sgrQ0Dz\ndYD6eM8sjwYaerEpMZKWnuTlU0uIeAdBaF6UKX72Q7JZQth1mZ7uX5O9xBWT4DHo\nM2ttK+ZyztOnPdGVL6pf+PkNZP+qSJK+mRVxJzT1AoGBANqiyWyH/D26pi1VvoMR\n1DyCWgJIa+Lm0CwR/CE0a1ATdSw1H96WvjEd5oHxlGER7Y9j0nfmvPabWFyNxKbu\nP8ly2aiFffAPKI2e2ZmXXrpcesj0IS5Uk5Mk/1hVwOtNLxGN/ayvk0DqwoIbvFEM\n2EzEYqr/xxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-2zjoi@fir-realtime-db-demo-xxxxx.iam.gserviceaccount.com",
  "client_id": "105636361475399593303",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-2zjoi%40fir-realtime-db-demo-fc492.iam.gserviceaccount.com"
}

Initialize Firebase DB instance

Download firebase.google.com/go/v4 and google.golang.org/api/option packages.

ctx := context.Background()

// configure database URL
conf := &firebase.Config{
	DatabaseURL: "https://fir-realtime-db-demo-xxxxx-default-rtdb.asia-southeast1.firebasedatabase.app",
}

// fetch service account key
opt := option.WithCredentialsFile("fir-realtime-db-demo-xxxxx-firebase-adminsdk-2zjoi-9b40ce1e42.json")

app, err := firebase.NewApp(ctx, conf, opt)
if err != nil {
	log.Fatalln("error in initializing firebase app: ", err)
}

client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("error in creating firebase DB client: ", err)
}

Add/Update data in Firebase

Let’s use the above-created firebase DB client and add/update some data in a database.

Unlike SQL, the Firebase database doesn't store the data in tables or records. It only stores data in form of JSON objects, hence it’s noteworthy to prepare a proper structure(in case of complex data structure) before getting started to store data that can be also handy for further processing.

Find more details about preparing an efficient JSON structure for firebase data.

// create ref at path user_scores/:userId
ref := client.NewRef("user_scores/" + fmt.Sprint(1))

if err := ref.Set(context.TODO(), map[string]interface{}{"score": 40}); err != nil {
  log.Fatal(err)
}

fmt.Println("score added/updated successfully!")

Get data from Firebase

It’s also handy to retrieve the stored data from Firebase DB.
We just need to provide a path from which it needs to read, unlike we use the primary key in the case of SQL.

type UserScore struct {
	Score int `json:"score"`
}

// get database reference to user score
ref := client.NewRef("user_scores/1")

// read from user_scores using ref
var s UserScore
if err := ref.Get(context.TODO(), &s); err != nil {
   log.Fatalln("error in reading from firebase DB: ", err)
}
fmt.Println("retrieved user's score is: ", s.Score)

It will print whichever score we have saved on the path user_scores/1 .

Delete data from Firebase

The below code will get the reference of the given path and delete it.

ref := client.NewRef("user_scores/1")

if err := ref.Delete(context.TODO()); err != nil {
  log.Fatalln("error in deleting ref: ", err)
}
fmt.Println("user's score deleted successfully:)")

Wrapping up!

It’s quite easy to collaborate between multiple platforms using Firebase's Real-time database. As there won’t be a need to do an API (HTTP) call for fetching or updating the data, the stuff you will implement will be lightning fast!

Find full implementation at Firebase DB CRUD using Golang.

Similar Articles


nidhi-d image
Nidhi Davra
Web developer@canopas | Gravitated towards Web | Eager to assist


nidhi-d image
Nidhi Davra
Web developer@canopas | Gravitated towards Web | Eager to assist


Talk to an expert
get intouch
Our team is happy to answer your questions. Fill out the form and we’ll get back to you as soon as possible
footer
Subscribe Here!
Follow us on
2024 Canopas Software LLP. All rights reserved.