Mobile Engineering Lead
Zinc MoneyMobile Developer & Founder
GamerboardSoftware Development Engineer 3
Acko General InsuranceAndroid Developer
Click LabsAndroid Developer
KalagatoAndroid Lead & Founding Member
RooterHello. So my name is Saurabh. I have been working in mobile tech around for eight, eight and a half years now, and I started graduated from Delhi College of Engineering or Delhi Technological University in 2015, then I've been, like, closely working around startups only since then. Uh, first company was ClickLabs, then press play for a brief amount of time, and then majorly in router for three years 10 months and then in echo for 3 years. And in router, I was working in as an Android lead. Router is an online streaming platform where gamers come and stream their content and earn money, basically. So in that, I work majorly around streaming the streaming your video on a WebRTC using Aurora and that was majorly around native Android. Then I onboarded with Flutter. Onboarded on Flutter, uh, in ACCO. ACCO is online general insurance platform. I was working in the health line of business. When I started there, I just I built the health app from ground up, building all the features for all the modules for health. It it included, uh, payments. It included policy management. It include included, uh, claims, filing of claims, and then health fitness tracking, Google Fit, and everything. So yeah. And, yeah, that's
Optimizing updates in Flutter, interacting with the restful APIs. Stick updates now. So, uh, by optimistic updates, I would assume it is related to updating the UI with APIs when we have integrated APIs with the system. So whenever like for example, you have background API calls in the Flutter app, we use state management basically to make this much more efficient and clean. And whenever we are making an API call on a background thread, we get that response and basically change those states on the UI, reflect the API call responses on the UI using the states. And whenever the state changes, we have 1 initial state. Let's say we have started the API call. We emit a state and that would be a loading state, for example. And when the API call completes, we get the response and we emit a state with the complete data point. So that way the UI thread doesn't block itself and we don't block the UI thread and whenever the API response comes, it's reflected on the UI. And let's say there's another case, for example, when we have multiple API responses, for example, on in UI, then we have, in that case, multiple states related to the different UI updates that we want to do. And depending on that each state, a particular set of UI content is
So, uh, with respect to artic architectural considerations, so when we are building a secure mobile app, first of all, for example, if it's using multiple external services, I'm assuming it is related to APIs or external libraries that we are using. First of all, our data shouldn't be exposed as form of any just a second. I'll rephrase it. Content providers are basically something in Android which, uh, which we use to expose a particular the app's content to any other app. Those sort of we should be if we are using them, we should have some sort of encryption into an encryption on it if we are providing the content and the keys should be kept within the sister apps, for example. But if we don't have such kind of things on the app then other things we can make our app secure is through orchestration of code and basically minifying the code of the release build, the signing of the APKs are APKs are signed before pushing them on any app store. Apart from that, if we are using external APIs, the connection should be made secure using https. Uh, with that, the keys, for example, if you're using any outside APIs, we have certain keys or secrets for accessing those content which are shared by different API vendors, for example. So all that are considered when we are using some external
By a mobile app. Listing the performance of API endpoints. So, uh, right. So, basically, when we are having our linear stress testing or when we are testing the performance of the API endpoints which our app is using, we generally use first of all the APIs are independently tested using tools like we can test them in Postman where a single API is called 100 times back to back or in parallel way to test their with the back end API, stress testing of the back end architecture or back end services. And on the app for stress testing a particular API, we test it on, for example, by changing the network connectivity. For example, if we are calling it on 3 gs network or if we are calling it on GPRS or Edge network or if we are calling on four gs or five gs or WiFi network, we test the APIs that respond on the basis of these different network types. Apart from that, we also check whether the APIs payload which we are getting is compressed in Gzip and also it's not a heavy payload that we are getting. If we are having a payload, for example, it's very subjective, but generally, we keep try to keep the payload in for max, max, like, 5 to 10 kilobytes so that and break that. If we have a bigger API response, we try to break that, payload into multiple APIs so that the UI or the app doesn't feel laggy or slow waiting for just 1 API response which takes a lot of time. And obviously, the response time should be less than one second. We try to make it less than 1 or 2 seconds so that the app doesn't feel laggy for an EPF, But it is all subjective depending on how much work the back end is doing. But when the back end receives the request and when the back end sends that request, that time obviously should be very less independent of what the back end is taking the time to process and getting the data, but we try to minimize that.
Right. Uh, so basically, for example, if you have a large scale flutter application, for example, a larger by large scale, I would say there are multiple modules. For example, payment is 1 module. For example, there is like in our case, Aco, uh, in Aco app, there were multiple line of businesses. 1 was health, 1 was travel, 1 was auto. In auto, there were 2 big modules of cars and bikes. Then there was life insurance. So everybody had their routing, routing to different pages for navigating to different pages. Now if all of that would be part of a central code or for us at a one place, it would be a very long and lengthy code and understandable code. For example, 2 line of businesses code or 2 modules could have same sort of signature for the same navigation. So first of all, the navigation at each module or this thing can be broken down into 2 things. One is the namespace of that module, for example, health slash or the module a slash module b slash module c slash. Then the modules individual pages can come in after that. And that itself can be part of the modules. Each module could have on its, uh, its own navigation, uh, reference file from which the navigation routes can be exposed. So whenever anything is built inside any 1 module, it can be part of that. If something is common to the complete app, that can be placed as the core or at the common navigation file. So for example, if I want to navigate to different modules, that can be part of the common navigation file or the navigation from splash screen to the main screen. That can be part of the common navigation file. But if I want to navigate to the homepage of a particular module, that can be part of that module. So I'll be referencing a particular navigation function of that module and it will be referring to that navigation route inside that module. That module will have the definition for all the navigation.
Design pattern will be implemented for data synchronization across multiple mobile platforms and why? So design pattern would be implemented for data sync between multiple mobile platforms? I'm not, uh, I'm if I'm not understanding it wrongly, uh, basically, our data the design pattern would be a central store of all the data which can be a back end API, which can be a Firestore or anything. Right? And the other plat multiple platforms would be, uh, okay. So basically, here, there is a two way communication. Whenever something updates, it should be sent across all the, uh, mobile devices. So a broadcaster and a receiver is sort of in play here where there's a consumer and producer. Consumer is basically our back end service which emits or sends out a broadcast to all the synced devices or all the linked devices to it. It's like the chat application that we have when the server sends anything and the phones are constantly listening to that particular endpoint. So it's like a channel or a socket you can say where there are multiple devices continuously connected to the endpoint And whenever something changes on it, all are updated at the in the same time. So the example of this would be a Firestore. Right? In Firebase Firestore, there are documents and entities and all the devices which are connected to it can be connected to it and they can keep the connection alive as long as the app is open, something like that. And then when anything changes in that document, everything is reflected onto the mobiles as soon as anything changes. So all the devices are constantly connected and the connection is kept alive And by thereby then, we can basically sync a particular content across multiple
Identify what might cause an exception to the same moment. We will probably dispose these Stateful widget. Stateful widget state. So it's a stateful widget. Stream dot periodic duration stream. Okay. There is a stream which is emitting something after every second and there's a subscription which is listening to it. Right? Now when we close this widget or this widget is disposed off, if we are not closing the stream, uh, it would be constantly emitting and basically there would this mode might I think when the apps when we keep on opening this custom widget or let's say this custom widget is part of a recycler view and that keeps on loading or creating this widget, there will be multiple streams which have been created in the system and are not disposing off. We are not canceling the subscription at any point. That should be canceled in this dispose function before super. Dispose is called and the stream should be closed. If you don't close it, there will be multiple streams existing in the system at one point and might cause out of memory error or memory leaks as well. Then we close this particular
HTTP request and response to improve error handling and maintain maintainability. So http.getgets a user, but we get the user data. As we throw the exception, fail to load user. So bay first of all, the r and API calls should be like a generic call for a particular request or sort of a request of a template. A response should be a part in the format of a template. That template should have the type of data that we are going to get. Right? And that should be part of the invoking call. Like, say, we are calling FetchUserData. First of all, the future here should be having a sort of type. Like in this case, it should be a user type which is a user object that we are returning by this function. The feature should have that. Next is when we are getting this JSON response, the response should be a class. Basically, it should have the see here. Response is basically a yeah. It's an object with status code 200, and the data is part of the body. Now we are decoding that body to get the user. Now basically, this would be repeated across this is a sort of a redundant thing and would be repeated across multiple API calls. So here, the the JSON dot decoder something should be actually part of the main API. Http.get should be moved to a particular, uh, this thing at network layer. And layer should be dealing with the API making the API calls and transforming those responses into an object. We'll be passing to the network layer what object type we need, what is the type of API call, and what is the API parameters and API input that we are calling. That network layer will be giving us the different after JSON dot decode is called and the responses turn into an object, that object will be sent to us through that network layer. That should be responsible to our network layer and we should be getting the objects at the end or the errors. Errors will just not be a simple fail to load user. To understand more about the error, it should be based on the status codes. Like for example if you are getting 500 or 501, it is an internal server error that you are getting or 502 for unreachable backend, unreachable host. 404 could be the API if we are not getting. All those errors should be specified explicitly as part of that error. Uh, error should be understandable, and that will be thrown by the network layer to the
Offline first mobile app using Flutter by data integrity is critical. So since an offline first mobile app, basically, everything is supposed to be, um, basically everything is being stored on the mobile itself. There is no external API communication or anything. So whatever we are storing, first of all, the local database that we are having, it should be encrypted and those keys should be part of Either we dynamically create those keys and refresh those keys on the server or add some if it's completely offline app, then we could have a salt which is baked into the Gradle and it's injected at the time of the app creation. Right? And that Salt, apart from that API key that we are having, will be basically encrypting the data for us and whatever data that we are storing on locally should be encrypted. First of all, The shared preferences file, their use should be minimalist because a rooted phone can be used to access that shared preference file and everything that we are storing in it, that should also be encrypted as well. If you're not using it for just just simple flags, even then we should just use it minimally, not for the user specific data. Apart from that, uh, the database, as I said, should be encrypted, and there should not be any open content providers. All should be signed for that specific app signature. And token creation and everything, yeah, everything should be on Firebase. Firebase token, we should be having that should be registered on Firebase. And since that since so that basically nobody can nobody else can have that particular package ID and create a replicating app. Right? So our app should be registered. And data integrity is good. And since we are not storing it online, the data is everything is being saved onto the device. For one thing here, what we can do is keep that we can ask or make that we can have that option of keeping the data as not part of the apps, the memory app storage in the file structure. We can keep it as part of a separate folder in the Android files storage and we can reference that particular thing or database whenever our app is installed. For example, if the user installs, we can store that whole data as part of our own apps folder and storage emulated and slash and the root path or any folder but not the Android's internal Android folder basically. Android folder for the app. We can have it part of on the root or anywhere else and whenever app is uninstalled relaunched, that same folder can be referenced and the data will be still there for the offline app. It won't it will not be destroyed unless until user goes specifically to that folder and deletes it. Clearing data won't affect the
So I haven't worked on React Native as such, but since Flutter is nearly the same thing, have the same principle. So Firebase backend, first first thing would be to create a package name, register that package name of Firebase, add our app, both Android drivers, and get the package dot, uh, the goalservices. JSON file and integrate with our Firebase services on the app. Next thing is to either use Firebase Realtime Database or Firestone. Both of them can be used depending on what do we want to do with it. Uh, so in this case, if we're using real time database, we would just be integrating the dependencies. Uh, Firebase there's a Firebase core dependency which manages the versioning, and then there are Firebase dash. In this case, it would be a in Flutter, there is a firebase dash, um, firestore, firebase dash packages, uh, or and in Android, in the Gradle, we can add the file based codependency and everything. And next thing is, I think, to have basically connection setup, create the structure on this thing. Decide on the structure or depending on your architecture or on your entities. Create that those entities on the database. Right? Or basically then write and read the data from it depending on whether if it's just to consume only data, we are not going to manipulate it. We can just read the data from it. If you want to write and update it, then you can write onto that data
So the key factors are basically when I'm integrating any third party APIs or anything. 1st, I'll go through the documentation, what and all they are using. Then I'll be checking out the branch from my project and just seeing whether if that and adding their dependency and checking if basically that adding that dependency isn't conflicting with any other. If there are any other conflicting dependencies, I will be resolving them or I'll be trying to resolve their versions. If still they're not being resolved, I'll be raising the query to the third party support. After that, the next steps are to initialize those libraries and that too depends whether if I want to initialize it in the application scope when the app launches or if I want to initialize it, then they are actually being used through the their scope is only limited to, for example, to a particular activity or a particular screen. And apart from that, what packages they are using and their internal are the basically keys. How are the keys being exposed? Are they through the developer dashboard or anything? Apart from that, security and everything can be changed whether the packages that basically which I'm integrating, what is the network traffic, what data are they taking at my end? We can track that In the debug applications, we can track the network payloads, what we are actually sending them, and what are the API calls that the package is internally doing. Uh, we can therefore have idea about what the third party application is intending to do, whether it is intending to do whatever it is you made for or is it doing something else? For example, if it's a chat application or anything, it should be active only when the screen is open and should be sending my payload. Apart from that, whether I want it or not. That's all. We should not be sending my device locations or anything unless until I ask that chat application to do. Similarly, uh, apart from that, what are the what's the size of that third party tool that I'm integrating? Am I integrating that? Am I increasing my app size by considerable amount or is it just a small change in the app size? That is also a big consideration. And it should be easily integratable and maintainable. For example, the packages version should be are those libraries continuously thoroughly updated? With time, are those out of date? Like, was the last change made 6 months ago, 1 year ago, or just like 1 month ago? That is also a key factor to understand whether it is maintained or not. Apart from that, is it available for all the platforms that I'm using? Or I'm is it that robust? Yeah. All these things I'll be