Wtf is Grpc? Part 2: Custom Notification(without Firebase) in Flutter and Golang.
Tags: flutter, go, grpc, mongodb
Published: 2023-09-30 08:22:57

Welcome back, intrepid tech explorers! If you survived the roller-coaster of gRPC, Flutter, and Golang from our last adventure, congratulations! You're now ready for Part 2: **"Wtf is gRPC? Part 2: Custom Notification (without Firebase) in Flutter and Golang."** 🎉

In this next thrilling installment, we'll tackle custom notifications without the Firebase safety net. Get ready to dive into the world of Flutter and Golang, where we'll craft notifications that are as unique as your favorite coding quirks. So, fasten your seatbelts and keep your code close; it's going to be a wild ride through the land of tech enchantment! 🚀💻✨

![Meme 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ceg80tqdvyayyxq35thb.jpg)

## Table of Contents: Navigating the Streaming Circus 🎪

- [The Streaming Showdown: gRPC Unleashed](#the-streaming-showdown-grpc-unleashed)
- [Let's Play with Data: The Streaming Playground](#lets-play-with-data-the-streaming-playground)
- [Setting Up the Golang Server: Where Code Meets Magic](#setting-up-the-golang-server-where-code-meets-magic)
- [Fluttering into Action: Your Magical Streaming App](#fluttering-into-action-your-magical-streaming-app)


## The Streaming Showdown: gRPC Unleashed
In simple words `A server-streaming RPC is similar to a unary RPC, except that the server returns a stream of messages in response to a client’s request. After sending all its messages, the server’s status details (status code and optional status message) and optional trailing metadata are sent to the client. This completes processing on the server side. The client completes once it has all the server’s messages.`

## Unary vs. Server Streaming: The Tech Battle of the Century

In this epic tech showdown, I am going to compare Unary Streaming and Server Streaming, with a touch of TV series for better understanding.

| Aspect                     | Unary Streaming       | Server Streaming       | TV Series Comparison       |
|----------------------------|-----------------------|------------------------|-----------------------------|
| Data Transfer              | Single requests       | Continuous data stream | *The Office* (Episode-by-episode) |
| Communication Overhead     | Less                  | Slightly more          | *Friends* (Constant chatter) |
| Real-time Updates          | Not suitable          | Ideal for real-time    | *Stranger Things* (Always suspenseful) |
| Complexity                 | Simpler               | More complex           | *Black Mirror* (Mind-bending) |
| Scalability                | Limited by requests   | Highly scalable        | *Game of Thrones* (Vast world) |
| Use Cases                  | Simple operations     | Real-time data streaming | *Breaking Bad* (Intense) |
| Resource Consumption       | Lower                 | Higher                 | *The Mandalorian* (High production) |
| Parallel Processing        | Limited               | Effective              | *The Big Bang Theory* (Many characters) |
| Error Handling             | Simple                | Handling errors in streams | *The Twilight Zone* (Mysterious) |
| Performance                | Suitable for small-scale | Suitable for large-scale | *The Walking Dead* (Epic) |
| Winner                     | Suitable for specific tasks | Ideal for real-time data | *Server Streaming Showdown!* |


![grpc-server-side](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f69rj8xhjxtszom4ihj2.png)

## Let's Play with Data: The Streaming Playground 

Let's play with streaming! Imagine that the client is a stand-up comedian whose job is to tell jokes, and the server, representing the audience, responds with laughter until they've had enough."

- Let's create required message and service.

**`joke.proto`**

```
syntax = "proto3";

package pb;
option go_package="github.com/djsmk123/server/pb";
//Response send by standup comedian to audience 
message Joke{
    string joke=1;
}
// Response Recieved by standup comedian from audience
message JokeResponse{
    string laugh_intensity=1;
};
```

**`rpc_services.proto`**:
```
syntax="proto3";
package pb;
option go_package="github.com/djsmk123/server/pb";
import "joke.proto";
service GrpcServerService {
    rpc ThrowAJoke(Joke) returns(stream JokeResponse){};
}
```

- Implement `ThrowAJoke()` function in golang.

```
func (s *Server) ThrowAJoke(joke *pb.Joke, stream pb.GrpcServerService_ThrowAJokeServer) error {
	for i := 1; i <= 10; i++ {
		response := &pb.JokeResponse{
			LaughIntensity: fmt.Sprintf("LOL %d", i),
		}
		if err := stream.Send(response); err != nil {
			return err
		}
		time.Sleep(1 * time.Second)
	}
	return nil
}
```
- Let's call service now.

![grpc-streaming-output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhwdnfpm4zqf08fnd3mh.png)

![meme1](https://media.tenor.com/91xjtSzXm6YAAAAC/crowd-laughing.gif)


---


## Setting Up the Golang Server: Where Code Meets Magic

We are going to create a notification service that will listen to a notification-gRPC streaming service in the background. If any new user is added to the MongoDB collection named users, we will send data to the listener, which will then display notifications in the application.


![notification-service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jti97l59jvis4gem4qop.jpg)


- Let's continue code from part 1,where we left.

`git clone git@github.com:Djsmk123/Wtf-is-grpc.git`

- Create a new message for the notification response that has to be returned by the server.

**`rpc_notification.proto`**

```
syntax="proto3";
package pb;

option go_package="github.com/djsmk123/server/pb";


message NotificationMessage{
    int32 id=1;
    string title=2;
    string description=3;
}
```

- Create new `rpc` in `rpc_services.proto`.
```
//keep everything same
//import NotificationMessage
import "rpc_notifications.proto";
//same 
service GrpcServerService {
//keep same 
// create new rpc function here
    rpc GetNotifications(EmptyRequest) returns (stream NotificationMessage){}
}
```
- Create equivalent code for golang from proto.
```
protoc --proto_path=proto --go_out=pb --go_opt=paths=source_relative \
    --go-grpc_out=pb --go-grpc_opt=paths=source_relative \
    proto/*.proto
```

- Create new package called `services` in root folder(`server`).

> We are using **goroutines** and **channels** to listen for changes in the database. If you want to learn more about goroutines, you can read this [blog](https://betterprogramming.pub/golang-how-to-implement-concurrency-with-goroutines-channels-2b78b8077984)

- Create new services `notification.go`.
{% gist https://gist.github.com/Djsmk123/ecef7010f997022f4b5ca124edcd367e %}

- Now just have to define `rpc GetNotification` in `gapi`. so create a new file `notification.go` in package `gapi`.
{% gist https://gist.github.com/Djsmk123/7048cbee85835420124646866e7f6b43 %}

- Wait, we can't listen change stream in `mongodb` without converting **standalone** to **replica set** more info [here](https://www.mongodb.com/docs/manual/changeStreams/).


- In terminal open path (windows)

`cd C:\Program Files\MongoDB\Server\<mongo-version>\bin`

- Execute this command
```
mongod --port 27017 --dbpath="C:\Program Files\MongoDB\Server\<mongo-version>\data" --replSet rs0 --bind_ip localhost
```
- Re-run mongo service

`rs.initiate()`

- Run server and let's test in `evans-cli`.

{% youtube PCSkI_i461Y %}


## Fluttering into Action: Your Magical Streaming App

- Add following dependencies to flutter project

```
dependencies:
  flutter_background_service: ^5.0.1
  flutter_local_notifications: ^15.1.1
  flutter_background_service_android: ^6.0.1
```

- Create equivalent code for dart 

```
protoc --proto_path=proto --dart_out=grpc:lib/pb proto/*.proto
```
- Create new services,called `notification.dart`

{% gist https://gist.github.com/Djsmk123/0c25b5a01296129118f79da4eb4682e5 %}

- Call notification service function in `splash_screen.dart`

```
 Future<void> initAsync() async {
    try {
      await NotificationServices.initializeService();
      //keep same
    } catch (e) {
      log(e.toString());
      navigateToLogin();
    }
  }
```

- Let's build application and listen for new user.

![flutter notification without firebase](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/osm2tlvnlp35mxhj2f1v.jpg)

Thank you for joining us on this journey so far! We've covered a lot in this series, from setting up the server-side of our application in Golang, handling notifications, to building a foundation for communication.

In the next and final part of this series, we'll explore one of the most exciting features of gRPC: bi-directional streaming. We'll be implementing a real-time chat service using Flutter and Golang. Get ready for a dynamic and interactive experience that showcases the power and flexibility of gRPC.

So, stay tuned and keep coding! We can't wait to see you in the last part of this series where we'll bring it all together and create a fully functional chat application.

If you have any questions or feedback, please feel free to reach out. Happy coding, and see you in the next installment!



## Source code : 
[Github Repo](https://github.com/Djsmk123/wtf-is-grpc/tree/part2)

## Follow me on 

- [Twitter](https://twitter.com/smk_winner)

- [Instagram](https://www.instagram.com/smkwinner/)

- [Github](https://www.github.com/djsmk123)

- [linkedin](https://www.linkedin.com/in/md-mobin-bb928820b/)

- [dev.to](https://dev.to/djsmk123)

- [Medium](https://medium.com/@djsmk123)