How do i connect Ionic/Angular Admin(or any user role) panel(UI) to firestore to write collections.

Guys please need help. Building an Angular-Ionic Eccommerce App, and i need to use a backend for data storage and user management etc.
But i have some issues, i dont know to connect an admin panel/dashboard to firestore, django(python) makes that part very easy, but firestore has some cool features and its more closer to Angular than Django especially with AngularFire.

Need help with how connecting a dashboard/admin-panel or any other panel/dashboard for other user roles can be done. Any help as soon as possible will save my day. Thanks and Happy New Year tho the year is few days old😂


Source link

CRUD OPERATIONS IN NODE JS WITH EXPRESS AND FIREBASE

Create, Read, Update and Delete are what is referred to as CRUD.
CRUD operations are present in almost every web app. In this tutorial I will explain how to perform CRUD operations in Node JS and Firebase.
I will assume that you have a project set up and ready.

CREATE OPERATION:
Let’s create a hypothetical user to demonstrate how to create and save data to the database

app.post('/create-user', (req, res) => 
    const name, email, password, phoneno, location  = req.body;
    const auth = firebase.auth();
    auth.createUserWithEmailAndPassword(email, password)
        .then((user) => 
            firebase.firestore().collection("users").doc().set(
                "name": name,
                "email": email,
                "phoneno": phoneno,
                "location": location,
            )
            .then(() => 
                res.send('User created successfully');
            );
        )
        .catch(err => 
            res.send(err);
        );
);

In the above code we are getting the user information ie name, email, password and location, from the request body, we then call the firebase auth method and use this auth method to authenticate the user profile using the user’s email and password

.then((user) => 
            firebase.firestore().collection("users").doc().set(
                "name": name,
                "email": email,
                "phoneno": phoneno,
                "location": location,
            )
            .then(() => 
                res.send('User created successfully');
            );
        )

Then we call an instance of Cloud firestore and save the user data in a document. The “.set()” method overwrites an existing document, if the document does not exist, it will create it with the data provided.

READ:
We will create a route that logs the user in;

app.post('/login', async(req, res) => 
    try 
        const email, password = req.body;
        await firebase.auth().signInWithEmailAndPassword(email, password)
        .then((user) => 
            firebase.firestore()
                .collection('customers')
                .where('email', '==', email)
                .get()
            .then((users) => 
                let value = users.docs[0].data();
                res.json(value);
            );
        );
     catch (err) 
        return res.status(400).send( message: err.message );
    
);

Here we call the firebase auth method to authenticate the data provided in the request body, if the data is authenticated successfully, we then go on to find the user document in our cloud firestore using the user email.

            .then((users) => 
                let value = users.docs[0].data();
                res.json(value);
            );

We then call the docs method on the result returned from the firebase query to get the result as a list and the pick the first document (should only contain one document) and return it.

FIND ONE DOCUMENT
Here we are going to query the cloud firestore collection “users” for one document using the email provided and return the first document

app.get('/find-user', async(req, res) => 
    const email = req.body;
    await firebase.firestore()
        .collection('users')
        .where('email', '==', email)
        .get()
    .then((users) => 
        let value = users.docs[0].data();
        res.send(value);
    );
);

FIRLTER DOCUMENTS BY MORE THAN ONE FIELD
We are going to query our cloud firestore and filter the data by more than one field in the document. Assume we want to find users in a particular location, that are also verified and also currently online.

app.post('/find-user', async (req, res) => 
    let location = req.body.location;
    let query = await firebase.firestore()
        .collection('users')
        .where('location', '==', location);

        if(query != "") 
            query = await query.where('verified', '==', "true");
        
        if(query != "") 
            query.where('status', '==', 'online')
            .get()
            .then(snapshots => 
                if(snapshots.empty) 
                return null;
                
                let results = snapshots.docs.map(doc => doc.data());
                return res.json(results[0]);
            );
        
);

The “.where” method returns a collection query which we first check to see if it is not empty, if it’s not, we then filter by other fields, then we loop through the results and return the data of the first document.

UPDATE:
We will use the “.update” method to update an existing document in the cloud firestore. It only works if the document already exists before calling the update method

app.post('/update-user', async(req, res) => 
    const name, email, phoneno, location  = req.body;
    try
        if(!req.body)
            return res
                .status(400)
                .send( message : "Data to update can not be empty");
        
        await firebase.firestore().collection('users')
        .where('email', "==", email)
        .update(
            name : name,
            description : req.body.description,
            phoneno : phoneno,
            location : location,
        ).then((ref) => 
            res.json(ref.data());
        );
    
    catch(err)res.status(500).send( message : err.message );
    
);

DELETE:

Delete operation is pretty straightforward, call the “.delete” method on the document you want to remove

app.post('/delete-user', async(req, res) => 
    const email = req.body;
    await firebase.firestore()
    .collection('users')
    .where('email', "==", email)
    .delete()
    .then((ref) => 
        res.json(ref.data());
    );
);

DELETE VALUE FROM ARRAY:

app.post('/delete-value', async(req, res) => 
    const email, value = req.body;
    try
        await firebase.firestore().collection('users').doc(email).update(
            [value] : firebase.firestore.FieldValue.delete()
        );
        res.json('successful operation');
    
    catch(err)res.status(500).send( message : err.message );
    
);

Source link

Integrate Firebase Authentication with Google Sign-In to SwiftUI app

SwiftUI framework is already in its third iteration and with that, it is well and truly on its way to production-ready applications. Such applications are certainly going to need some sort of authentication. Since authenticating users can be tricky, you may want to rely on third-party solutions for that, such as Firebase. Question is then, how does one integrate Firebase and Google Sign-In to SwiftUI application?

This article will show you how to create iOS application using SwiftUI, create Firebase project and then use Firebase Authentication to integrate Google Sign-In SDK to your SwiftUI application.

Within this article we will cover following topics:

  • Creation of Firebase project

  • Creation of SwiftUI Lifecycle application

  • Handling dependencies with CocoaPods

  • Handling authentication within our code

  • Designing UI elements



Creation of Firebase project

In order to use Firebase in our SwiftUI app, we need to create new Firebase project in

Firebase console. Create new project by clicking on Add project.

Once Create a project page opens, enter project name.
Screenshot 2021-11-25 at 15.30.35.png

Next step is either enabling or disabling Google Analytics. It is not necessary for this demo, so it’s up to you to enable it.

When project’s Dashboard opens, click on iOS icon.
Screenshot 2021-11-25 at 15.37.28.png

Next, fill out form for registering the app. Apple Bundle ID is important since it needs to be the same as bundle identifier, we will use later in Xcode project. Other two fields are optional. App Store ID is only needed if app will be uploaded to the App Store which we are not doing in this tutorial.

Screenshot 2021-11-28 at 09.40.27.png

Click on Register app.
Next, we need to download GoogleService-Info.plist file which will be added to Xcode project later.

Screenshot 2021-11-25 at 15.45.33.png

In steps 3 and 4 just click Next since we will cover them in more detail later in the tutorial. To finish registering the app, click Continue to console.

Almost finished with setting up Firebase project. Lastly, we need to enable Authentication.

Click on Authentication, and then on Get started.
Screenshot 2021-11-25 at 15.50.15.png

Now choose Google as Sign-in method provider.

Screenshot 2021-11-25 at 15.52.26.png

Finally, enable it by toggling Enable button, add Project public-facing name and Project support email. Save this changes by clicking on Save button.

Screenshot 2021-11-25 at 15.53.33.png

We are done with Firebase settings and now we are moving to actual coding!



Creation of SwiftUI Lifecycle application

Next step is to actually create Xcode project. Open Xcode, select option Create a new Xcode project. Once new window opens, make sure that iOS is selected in header and then select App. Click Next.

Now we need enter some details about project.

  • Product Name: demo
  • Organization Identifier: com.firebase
  • Interface: SwiftUI
  • Language: Swift

Core Data and Tests are not needed for this tutorial, so it is up to you to include them into the project.

Screenshot 2021-11-28 at 09.38.27.png

Click Next and then choose folder where you want to save Xcode project.

Great! We are ready for next section, handling dependencies with CocoaPods.



Handling dependencies with CocoaPods

CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 86 thousand libraries and is used in over 3 million apps. CocoaPods can help you scale your projects elegantly.

To handle project dependencies, this tutorial will use CocoaPods. If CocoaPods is not installed on your development machine, follow this Getting Started guide on official CocoaPods page.

Using Terminal, navigate to your project. Use command similar to this one: cd your/project/path.

Once in your project path, initialize empty pod file by executing pod init command. Open newly created Podfile to add dependencies needed for this project.

Add following content:

target 'swiftui' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for swiftui
  pod 'Firebase/Core'
  pod 'Firebase/Auth'
  pod 'GoogleSignIn'

end

To install these dependencies, execute pod install command.

Awesome! Project setup is done, and its dependencies are successfully installed.



Handling authentication within our code

First step is to take GoogleService-Info.plist file we downloaded it in Creation of Firebase project section and drag&drop it into Xcode project. Once file is added to the project, we need to add REVERSED_CLIENT_ID key to project configuration.



Handling REVERSED_CLIENT_ID key

Do the following:

  1. Open your project configuration: double-click the project name in the left tree view. Select your app from the TARGETS section, then select the Info tab, and expand the URL Types section.

  2. Click the + button, and add a URL scheme for your reversed client ID. To find this value, open the GoogleService-Info.plist configuration file, and look for the REVERSED_CLIENT_ID key. Copy the value of that key and paste it into the URL Schemes box on the configuration page. Leave the other fields blank.
    When completed, your config should look something similar to the following (but with your application-specific values):
    Screenshot 2021-11-27 at 21.45.09.png

Now we can move on to some coding!



Adding AppDelegate

Since iOS 14 and SwiftUI 2.0, Apple added ability to include AppDelegate to SwiftUI Lifecycle app which we will need to add to our project.

Right click on project in Xcode left tree view and then select New file…. Add new Swift file named AppDelegate. Once create, add following contents to the file:

import Firebase
import GoogleSignIn

class AppDelegate: NSObject, UIApplicationDelegate 

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
    ) -> Bool 
        FirebaseApp.configure()
        return true
    

    func application(
      _ app: UIApplication,
      open url: URL,
      options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool 
        return GIDSignIn.sharedInstance.handle(url)
    



Adding helper functions

For signInWithConfiguration:presentingViewController:callback: method we will use later, we need to provide presenting ViewController and GIDConfiguration configuration thus we need to implement two helper functions.

GIDConfigurationExtensions.swift:

import Firebase
import GoogleSignIn

extension GIDConfiguration 

    /// Get GIDConfiguration instance by providing clientID from GoogleService-Info.plist file
    /// - Returns: GIDConfiguration instance
    static func getGIDConfigurationInstance() -> GIDConfiguration 
        GIDConfiguration(clientID: FirebaseApp.app()?.options.clientID ?? "")
    

UIApplicationExtensions.swift

import UIKit

extension UIApplication 

    /// Get root UIViewController of application. If for whatever reason, UIViewController can not be accessed,
    /// invoke fatalError() since UIViewController instance is crucial for application for work properly.
    /// - Returns: root UIViewController
    static func getRootViewController() throws -> UIViewController 
        let scenes = UIApplication.shared.connectedScenes
        let windowScene = scenes.first as? UIWindowScene
        let window = windowScene?.windows.first

        guard let uiViewController = window?.rootViewController else  fatalError() 
        return uiViewController
    

With this finished, we can move start implementing ViewModel.



Implementing LoginViewModel

Create new Swift file named LoginViewModel.

LoginViewModel:

import Firebase
import GoogleSignIn

final class LoginViewModel: ObservableObject {

    @Published var isUserLoggedIn = false

    func signIn() 
        do 
            let config = GIDConfiguration.getGIDConfigurationInstance()
            let uiViewController = try UIApplication.getRootViewController()

            GIDSignIn.sharedInstance.signIn(with: config, presenting: uiViewController)  user, error in
                guard error == nil else  return 
                guard user != nil else  return 
                self.isUserLoggedIn = true
          
         catch 
            print(error.localizedDescription)
        
    

    func signOut() 
        GIDSignIn.sharedInstance.signOut()
        isUserLoggedIn = false
    
}



Designing UI elements

Now comes last piece of the puzzle. Designing UI elements using SwiftUI framework and connecting UI with business logic we implemented earlier.



LoginView

Create new SwiftUI View file named LoginView.

LoginView:

import SwiftUI

struct LoginView: View {

    @EnvironmentObject var viewModel: LoginViewModel

    var body: some View 
        VStack 
            Spacer()

            Button(action: 
                withAnimation 
                    viewModel.signIn()
                
            ) 
                HStack 
                    Text("Sign in with google")
                        .fontWeight(.bold)
                
            
            .foregroundColor(.white)
            .padding()
            .frame(maxWidth: .infinity)
            .background(.black)
            .cornerRadius(12)
            .padding()

            Spacer()
        
    
}

struct LoginView_Previews: PreviewProvider 
    static var previews: some View 
        LoginView()
    

LoginView will look something like this:

Simulator Screen Shot - iPhone 12 - 2021-11-28 at 10.41.25.png



HomeView

Create new SwiftUI View file named HomeView.

HomeView:

import GoogleSignIn
import SwiftUI
import SDWebImageSwiftUI

struct UserDetailView: View 

    let user: GIDGoogleUser?

    var body: some View 
        VStack 
            HStack 
                Text(user?.profile?.name ?? "")
                    .bold()
                    .font(.title2)

                Spacer()

                WebImage(url: user?.profile?.imageURL(withDimension: 75))
                    .resizable()
                    .placeholder(
                        Image(systemName: "person.fill")
                    )
                    .indicator(.activity)
                    .transition(.fade(duration: 0.5))
                    .frame(width: 75, height: 75, alignment: .center)
                    .scaledToFit()
                    .clipShape(Circle())
            
            HStack 
                Text(user?.profile?.email ?? "")
                    .bold()
                    .font(.subheadline)
                Spacer()
            

            Spacer()
        
        .padding()
        .frame(height: 150, alignment: .center)
        .background(.thickMaterial)
        .cornerRadius(12)
    


struct HomeView: View {

    @EnvironmentObject var viewModel: LoginViewModel
    private let user = GIDSignIn.sharedInstance.currentUser

    var body: some View 
        VStack 
            UserDetailView(user: user)

            Spacer()

            Button(action: 
                withAnimation 
                    viewModel.signOut()
                
            ) 
                HStack 
                    Text("Sign out")
                        .fontWeight(.bold)
                
            
            .foregroundColor(.white)
            .padding()
            .frame(maxWidth: .infinity)
            .background(.black)
            .cornerRadius(12)
            .padding()
        
        .padding()
    
}

struct HomeView_Previews: PreviewProvider 
    static var previews: some View 
        HomeView()
    

HomeView will look something like this:

Simulator Screen Shot - iPhone 12 - 2021-11-28 at 10.41.52.png



Connecting all together

All that is left to do is to connect it all together in DemoApp and ContentView.

DemoApp:

import SwiftUI

@main
struct DemoApp: App 

    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    @StateObject var viewModel = LoginViewModel()

    var body: some Scene 
        WindowGroup 
            ContentView()
                .environmentObject(viewModel)
        
    

ContentView:

import SwiftUI

struct ContentView: View 

    @EnvironmentObject var viewModel: LoginViewModel

    var body: some View 
        if viewModel.isUserLoggedIn 
            HomeView()
         else 
            LoginView()
        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

This is it! Integration of Firebase Authentication with Google Sign-In to SwiftUI application is done and our project is ready to be run on emulator or physical device!



Conclusion

Thank you for reading and and I hope this article was useful for you since integrating Firebase Authentication with SwiftUI Lifecycle application is not exactly straightforward.

If you like my content and find it useful, please consider following me here on Hashnode. If you are feeling extra generous, please consider buying me a coffee.

Connect with me on LinkedIn.


Source link

A-in-depth look of my Confession app

Finished Product Linkhttps://conphession.netlify.app/
Source Codehttps://bit.ly/3xjyYJ9

To contribute join our SLACK Workspace



What is Confession App?

Confession is a fully functional social media cum dating app which we developed for our fellow college mates so that they can post whatever they want to confess. They can confess publicly, privately and anonymously. Earlier our college mates were using an Instagram page to do the same, which we believe is a less democratic way as its up to the admin of the page to selectively post the confessions. This triggered us to create an app which does the same in a more democratic fashion and with better minimalistic UI and even more features like chat app, therapy room, toxic comment detector etc.



Objectives

We intend to achieve the following objectives by developing this app –

  1. Create an online dating cum social media platform that replaces the existing dependence on an Instagram page.
  2. Provide a safe place for our college mates to post confessions where they can confess publicly, privately, and anonymously in a more democratic way.



Intended Audiences

Though we created this app for our college mates but its for anyone who –

  1. wants to confess to their college crush.
  2. wants a democratic platform to share his/her opinion publicly or anonymously.
  3. wants a safe place for confessing privately while keeping their details confidential.
  4. wants a platform where they can chat with their mates



Features and Functionalities

  1. Realtime Update

    1. This feature is made possible by technologies like React and Firebase Real-time Database.
    2. Any changes made to the database will be reflected real-time on the web page.
  2. Anonymous Confession

    1. One doesn’t need to authenticate to confess anonymously. If someone wish to confess anonymously, we have created a separate account for that. So when someone confess anonymously, it gets posted under the name of that account and not under name of user’s account. So we have no way to know who have posted that confession.
      b. There is also a downside to confessing anonymously, user can’t update and delete their anonymous confession. For now we decided to keep it that way.
  3. Authentication

    1. Although you can anonymously confess on our platform, but in order to publicly confess and access some features one needs to authenticate.
    2. Confession provides you two ways to authenticate – google authentication and email authentication
    3. Even after authentication, one can easily confess anonymously.
    4. To make the authentication possible we have used Firebase Authentication.
  4. User Profile and Profile Engagement

    1. When user authenticate, a profile gets created with their chosen username.
    2. One can share their profile and also other’s profile on other social media platforms.
    3. One can make changes to his/her profile, they can change their username, avatar etc
    4. One can also follow and unfollow other’s profile. They follow their profile by default. So every user have at least one follower and following by default.
  5. Confessions CRUD

    1. Once authenticated user can create, read, update and delete their confessions publicly. Though that’s not the case with anonymous confessions.
    2. Users can also confess privately in the therapy room. This feature is under development though. Nobody will be able to see the private confessions except for the website admin and the user and the admin will make sure to keep those confessions confidential.
  6. Confessions Engagement

    1. One can like and unlike the confession.
    2. One can share the confession.
    3. One can comment on the confession.
    4. One can report the confession. (Under development)
  7. Comment CRUD

    1. Once authenticated users can comment on each other’s confessions.
    2. User can perform CRUD operation on their own confessions.
  8. Nested Comments (Under Development)

    1. Once authenticated user can comment on each others comment.
    2. We are keeping the comment reply thread to one level only for now.
  9. Responsive and Masonry UI

    1. The web app is completely responsive. The UI is compatible with all the device. To make the website responsive we used Bootstrap with React.
    2. All the confessions are arranged in masonry fashion. For masonry look we have used an NPM package, react-masonry-css to do the job.
  10. Infinite Scroll (Under Development)

    1. One should be able to see 30 confessions at a time in masonry pattern.
    2. Instead of doing it paginated way, we are using infinite scroll.
  11. Toxic confession and comment detector (Under Development)

    1. Another problem we are anticipating with Confession App is Content Moderation.
    2. Instead of using man-power for moderating the content, we are planning to deploy an ML Algorithm to filter the toxic confessions and comments and hide them.
  12. Integrated Chat App

    1. Confession also has an integrated chat app.
    2. For this purpose we are using an React Chat Engine API.
  13. Integrated Therapy Room for private confessions (Under Development)

    1. One can confess privately to the site admin in the therapy room.
    2. The private confessions will be kept confidential at all times.
    3. Private confessions can also be posted anonymously.



Limitations

  1. Update and Delete Problem with Anonymous Confessions

    As I mentioned, Anonymous Confession doesn’t goes under any user’s account, it goes under a anonymous user’s account which I have created for this purpose. So we have no way of knowing who created that anonymous confession. Since a user can only delete their own confessions and not others, therefore there is no way of updating and deleting anonymous’ confessions.

    Though we can make changes to Database schema and associate that anonymous confession to the user’s account, but then the site admin would know who created the confession which contradicts what anonymous confession stands for. So we decided to keep it that way.

  2. Content Moderation

    An advantage that that Instagram Page has over our app is content moderation. All the confessions goes through the page admin, and the admin choose which confessions to post and which not. Though that’s not the most democratic way of posting confessions, but they have advantage of filtering the abusive and toxic once, which we don’t have.

    To tackle this issue, we are creating a TOXIC confessions and comment detector. We are letting the algorithm decide which confessions to keep and which to hide. But there’s another catch here, since we don’t have enough data of the confessions now, we can’t exactly train the model on our data, we have to rely on data from some other source, hence the model will be prepared accordingly.

  3. 3rd party dependency for Chat App

    As we mentioned, Confessions App has an integrated chat app for which we are using React Chat Engine. One limitations it poses to us, that it deletes the chats in a few days, therefore the users won’t be able to see their chats after few days.

    To overcome this issue we are planning to create a custom chat app from scratch.

  4. SEO (Search Engine Optimizations)

    We are using React library to build the user interface and it’s not good with pre-rendering the page, hence our app suffers with SEO because search engines and web crawlers won’t be able to see the content of the page as its not pre-rendered on server.

    To overcome this issue, we are planning to change the entire codebase of our project from React.js to Next.js, which is a react based framework and is good at Server Side Rendering and hence SEO.




Source link

My First Android App🎉😊



Solution#Hub-:

Solution#Hub-: Social app for helping students to solve their doubts



Inspiration🌠

Academic success is important because working people will need higher levels of education to tackle the technologically demanding occupations of the future. … Mostly these days every student is engaged in improving their day today’s study .Really sometimes getting an exact or amazing approach of a question is not that easy,to solve this dilemma ,I came across the idea of solution sharing platform , socially and I build the Solution#Hub.



What it does🚀

Solution#Hub is a social solution sharing app for the doubts of anybody in any area they are facing trouble.
First is opens with authentication screen using your email id and password then , one should login if account is already created otherwise ,first create account via clicking the create account button. Then a app logo splash screen appears for few seconds and you enters in the zone of lots of doubts of the peoples, Now search according to the subject which you want to solve using search-bar and give your solution to someones doubts. Don’t forget to ask for feedback i.e stars ,yes the app has feature ,-more stars you have more up will be the your posted question and answer as well.
And if you don’t have any solution ,No worries click the circular post button and post your question and wait who will answer it first.It only takes 15 seconds because I used timer for it.
Yes, app also have the special features for questions of aptitude ,all aptitude doubts will appears under one
tab,which makes it more useful as, mostly students find mathematics to hard as compare to other subjects. and feel free to logout if don’t want yourself to be logged in.



How I built it🔨

bar-bar
I started off by creating a prototype in Figma. The mobile application was built using Kotlin and Android-Stusio as tool. We made use of Firebase-Firestore for authentication and for saving user data.I used Picasso library for string-url to image parsing.



Challenges I ran into🔴

I ran into some problems with On each item click in Recycler View as to provide different solutions to every question posted on the app.But yes besides it firebase firestore was very new to me, i was challenge task for me to connect my Ui to firestore ,Moreover how to Load images using Picasso Library from image url. And publishing to google play store,creating singed APK bundle was very new to me but finally i did it.



Accomplishments that I’m proud of🎖

I am able to create our proper authentication system along with forget password option which I never really tried before. I also explored Firestore in a deep way and got to understand how a few things worked a particular way. Making the Nested recycler view work was tough but finally i was able to work properly as to provide different solutions to a single question.



What I learned📚

I got more experience in kotlin and firebase-firestore by building this application. Got to learn about different authentication systems and how everything interacts in the kotlin application during auth. I also wished to integrate video solutions in the app and hence got a chance to work around how video solution parse using url.And how to make app available on google play store.



What’s next for Solution#Hub🎉

The current point system that I have is dynamic but I would love to introduce video solutions and scanning the question option into the application to make the whole experience even more rewarding.



Project Gallery📷

gallert



Try it out here

You can download It from google play store
Download it here – Solution#Hub
It has 100+ downloads recently.


Source link

How to Emulate Firebase Auth

I was recently building an app in which I was trying to integrate Firebase Authentication and Firebase Realtime Database. But I ran into a problem pretty quickly while I was testing things locally.

Even though Firebase has a super amazing Emulator Suite for local testing, authentication is not included. To me, this meant that the lovely auth-based Realtime DB rules I’d crafted were impossible to test locally unless I modified my DB rules beforehand. But that doesn’t make for a very good permissions test, does it? There is an open issue on GitHub for addressing this, but at the time of writing, no solution has yet been included in the emulator suite.

Update 2020-10-27: Firebase Auth is now part of the Emulator Suite! Upgrade the Firebase CLI to version 8.14.0 or greater to use it. If that’s all you were looking for, the rest of this post might not be useful to you, but feel free to keep reading for a more detailed look at Firebase Auth and my general philosophy towards testing and modularization.

I spent a bunch of hours trying to figure out how to string things together with Band-Aids and glue to do something that honestly seems like a pretty basic requirement for DB testing: Test my auth rules in both development and production without modifying the very security model I’m trying to test. After all, who would want to do “real” permissions testing for the first time in a production environment??

Nothing was working. I was stuck. I missed. Then I missed again. Then I got sad. I had a popsicle. And then I passed out in the snow.

Just kidding on the last few, but what I did do what have an epiphany in the shower. I do some of my best thinking there. Anyone else? No? Okay. Moving on.



The Solution

My app in particular is using Google Login and the Google auth provider, so that’s what I’m going to focus on here, but I believe this approach would translate to other auth providers as well.

The key to making this work is abstraction. Take any Firebase call that you’d normally make and hide it behind a function that may or may not do the same thing. Usually, it’s the same sort of thing with some extras sprinkled in.

In this case, we’ll be looking at the firebase.initializeApp function. In the normal production environment, this is super simple. We pass in a siteConfig object and we’re on our merry way. However, when working locally and/or with Firebase Emulators, this doesn’t work one-for-one. In the docs, they indicate that we should use initializeTestApp instead to perform our initialization. This comes from the @firebase/testing module as opposed to the firebase/app module. This might seem perfect on the surface, but the issue is that anywhere we might normally use firebase.<sometThing> to interact with the default firebase app, we can’t. We instead need to work with the app instance returned from the call to firebase.initializeTestApp(). By extension, this means we should structure our code so that we’re always using app.<someThing> in favor of firebase.<someThing>, regardless of whether we’re using initializeApp or initializeTestApp.

Again, this doesn’t seem too bad on the surface, but there’s one more catch: In each case, the app instance (as provided by initialize*App(siteConfig)) is slightly different. Namely, app.auth() is not a thing for apps initialized via initializeTestApp().

This is the crux of the auth emulation problem. And this is what we are going to solve. Let’s take a look at some code.

Here is a utility function to initialize either a test or production app and return it:

const createApp = async (onAuthStateChanged) => 
    const firebase = await importFirebase()

    if (isDevelopment) 
        const app = firebase.initializeTestApp(siteConfig)

        // set up custom hooks for auth mocking
        app.__internal__ = 
            onAuthStateChanged
        

        return app
     else 
        const app = firebase.initializeApp(siteConfig)

        // Set up the auth observer
        app.auth().onAuthStateChanged(onAuthStateChanged)

        return app;
    

There’s a lot going on here, so let’s break it down line by line.

const createApp = async (onAuthStateChanged) => {

I went with async here because, in a couple lines, you’ll see some dynamic imports. More on that in a sec. The other important piece here is that this createApp function takes an onAuthStateChanged callback and not a siteConfig object like initializeApp. Since we control the module containing this abstraction function, we can put our siteConfig object here too for easy access. I mean, you can put the siteConfig wherever you want, but to me, it makes sense to have the same module own the config block and the utility functions since the goal is to drive all Firebase-related functions through this abstraction module.

The onAuthStateChanged callback will be called when—you guessed it—the auth state changes. In the production case, we can simply set up an auth observer in the usual manner, but in the development case, it’s a bit more interesting. More on that in a sec.

const firebase = await importFirebase()

Here’s another layer of abstraction. We want a reference to Firebase as a module, and more specifically we might want a reference to the “testing” version of Firebase, but we don’t actually care how it is obtained. Dynamic imports are a huge help here. This is what the definition of importFirebase looks like:

const importFirebase = async () => 
    if (isDevelopment) 
        return await import('@firebase/testing')
     else 
        const firebase = await import('firebase/app')

        await import('firebase/auth')
        await import('firebase/database')

        return firebase
    

There’s nothing too surprising here. We are either importing “test” Firebase from @firebase/testing or we are importing “real” Firebase from firebase/app along with our other Firebase dependencies. Dynamically importing “real” Firebase is a little more involved, but it’s basically the traditional way of doing it converted to dynamic import-form.

I feel like this is a good time to mention that the reason for using dynamic imports here is so that you only ever end up importing either the test Firebase or the production one, but never both. Dynamic imports give us that flexibility.

The astute reader might realize that even with dynamic imports, Webpack will still bundle both modules into the output since we don’t know until runtime which type of environment we’ll be in. While this is true, it can be avoided by splitting the vendor modules out as part of the build and filtering out one of the two Firebase chunks, depending on the build type.



Development Mode

if (isDevelopment) 

Assuming this is a React app created via create-react-app, we can calculate whether or not this is a development build by looking for process.env.NODE_ENV === 'development'

const app = firebase.initializeTestApp(siteConfig)

Next, we need to initialize the test app using the now-obtained Firebase module, providing it our siteConfig as usual. There’s a key piece that needs to exist in the siteConfig for this to work though: An auth block. Here’s an example config:

const siteConfig = 
    apiKey: '...',
    authDomain: window.location.host,
    databaseURL: isDevelopment
        ? 'http://localhost:9000?ns=...'
        : 'https://....firebaseio.com',
    databaseName: '...',
    projectId: '...',
    storageBucket: '....appspot.com',
    messagingSenderId: '...',
    appId: '...',
    measurementId: '...',
    auth: 
        uid: 'u111111',
        email: 'u111111@example.com'
    


That auth block is the key because that means that we can “inject” a user/email into the app manually as we see fit. There’s a caveat though… Since this isn’t real auth, we’ll never get onAuthStateChanged callbacks fired. We’re going to need to do that ourselves. And the first step towards doing that is to store a reference to the provided callback in our test app for later:

// set up custom hooks for auth mocking
app.__internal__ = 
    onAuthStateChanged


return app

Here I chose __internal__ as a namespace that I figured nobody would collide with, but this could just as easily have been any other unique key on the app object.



Production Mode

The other case to consider here is the production case. Let’s take a look at the else block:

 else 
    const app = firebase.initializeApp(siteConfig)

    // Set up the auth observer
    app.auth().onAuthStateChanged(onAuthStateChanged)

    return app;

This is very similar to what happens in development except we end up importing “real” Firebase and setting up an actual auth observer with that callback we took in as an argument.

All of this is to say that we can now call

const app = MyFirebaseUtils.createApp(onAuthStateChanged)

to get back a firebase app that’s ready to go with either emulated auth in development or real auth in production.

I recommend holding onto this app instance in your application state so that it can be provided to any abstraction functions that may depend on it, such as simulating a login in development mode.



Simulating onAuthStateChanged

For any function we have that would trigger a login (or logout), we can add in a separate development-only flow in which we manually fire an onAuthStateChanged event. Looking at the docs, those events are either passed a user or null depending on whether the user is logged in or not.

If our production flow for logging in a user looks like this:

const doGoogleLogin = async (app, onSuccess, onFailure) => 
    const firebase = await importFirebase()
    const provider = new firebase.auth.GoogleAuthProvider()

    // Show the actual login popup. Succeeding here will update the internally managed uid and
    // auth of the app, which allows subsequent database calls (and other stuff) to work.
    app.auth().signInWithPopup(provider)
        .then(onSuccess)
        .catch(onFailure)

Then we can add in a development flow, like this:

const doGoogleLogin = async (app, onSuccess, onFailure) => 
    if (isDevelopment) 
        // https://firebase.google.com/docs/reference/js/firebase.auth#usercredential
        onSuccess(
            credential: 
                accessToken: TEST_ID_AUTH_TOKEN
            ,
            user: 
                uid: siteConfig.auth.uid
            
        )

        // Fire a simulated onAuthStateChanged event, passing it the user from our siteConfig.auth block
        app.__internal__.onAuthStateChanged(
            uid: siteConfig.auth.uid,
            getIdToken: () => (TEST_ID_AUTH_TOKEN)
        )
     else 
        // production flow
    

And there you have it! A sorta-kinda way to emulate auth from within a Firebase-enabled app. Hopefully you find this useful. I’ve been successfully using this approach in my project to help with offline testing using Firebase emulators.


Source link

Firebase Authentication with GetX in Flutter



Introduction 🎉

You know about GetX. It is an extra-light and robust solution for Flutter. It combines high-performance state management, intelligent dependency injection, and route management quickly and practically.

I won

I’m going to be honest; I’m not that pro at using GetX. So one day, I wanted to use GetX to make a flutter app with firebase authentication to understand better, but I was confused. Then it took me some time to figure out how it was working, and eventually, I succeeded and fell in love with the world of GetX.

I won



Let’s Get Started 🎯

I will assume that you have a starter template setup to enter email, password, or a button to login with Gmail. Let’s list the steps necessary to make the authentication process.



Steps 👣



1. Configuring the Flutter Project



2. Connect App to Firebase



3. Creating the Auth Controller



4. Inject the auth controller



5. Login or Signing up Users



6. Success

I won



1. Configuring the Flutter project ⚙️

Let’s add the necessary packages that we’re going to use throughout the application.

Copy the dependencies to your Pubspec.yaml file. I am using the latest version available now at this moment.latest version available now at this moment.



2. Connect App to Firebase 🤝

Now we have to connect our app to firebase. First, go to the firebase console and create your project if you haven’t already. You will see an option to add an app to firebase. Depending on your preference and requirement, do that. The steps are pretty straightforward, and firebase will show you what to do and how.

Firebase Console

Don’t forget to enable the Email/Password Sign in and Google Sign In methods.

Sign In Method



3. Creating the Auth Controller 🎮

First, let’s make a constant file for the sake of simplicity and not to get confused or code duplications. Copy the below codes and paste them into your dart file inside the lib folder.

Suggestion: Make a folder inside of the lib folder titled Constants.

Now let’s create the Auth Controller where all of our business login related to Firebase Authentication will work. Just copy the below codes and paste them into your dart file inside of your lib folder.

Suggestion: Make a folder for titled Controller.



4. Inject the Auth Controller 💉

We have created the Auth Controller, but how are we going to use it? Let’s hop into the main.dart file and make some changes to our code.

Here, we are initializing the firebase and injecting the AuthController instance in the 4th line.

Sign In Method

Our dependencies are completed and initialized. Now let’s sign up some users.



5. Login or Signing up Users 🙋‍♂️🙋‍♀️

I assume you have a basic or super beautiful Signup or login screen ready. If not, you can copy my code for the screen, but note that it’s a super simple screen.

The above code is pretty self-explanatory. There are just two (2) text fields for email and password, one button to login and one to Register / Signup. The last elevated button is for the google authentication popup.



6. Success 🎉

You just implemented Firebase Authentication in Flutter with GetX.



Note for the reader 📒

This is my first time writing a medium story but you know you can press the clap👏 button 50 times? The higher you go, the more it motivates me to write more stuff for you!

I have a Youtube Channel Named “Coding with Imran”

Do subscribe to my channel if you want to get future updates!


Source link

Function Store – New functionality installed with a click.

Hey Everyone – Functions Store just launched on Product Hunt and we would love your feedback!
We’ve spent that last few months building:

  • A Marketplace of reusable, expert-built, and well-tested Google Cloud Functions
  • A Platform of tools to simplify building web apps on Google Cloud and Firebase
  • An opportunity for developers around the world to generate a new income stream
  • 20x faster to implement new features for your web app
    Check Us Out Here: https://www.producthunt.com/posts/function-store

Thanks to everyone who take time out of their busy days to help support by voting and providing feedback!


Source link

"npm" Command Cheat Sheet

Welcome back to a new blog post. Throughout my uses of npm and creating applications in angular, I have found a set of commands that I keep coming back to to use again and again. While they’re all used very commonly, it might be heard to remember them all of the time. So without any further ado, here they are for your convenient use! Hope it helps.



To install node.js

 # To install node.js
 # Install from the below official download link.
 # https://nodejs.org/en/#download



To install typescript

# To install typescript
npm install typescript -g



To install angular CLI

#  To install angular CLI
npm install @angular/cli -g



To check angular version

# To check angular version
ng version



To check the existing installed paths of node.js

# To check the existing installed paths of node.js
where node



To create new angular app

# To create new angular app
ng new <app_name>



To create module

# To create module
ng g module <module_name>



To install dependencies

# To install dependencies
npm install



To run or serve app

# To run/serve app
#To serve app => cd to the app folder and run
#Note:- npm start also will call ng serve and start the application.
ng serve



To create service

# To create service
ng gnerate service service_name



To generate interface

# To generate interface
ng generate interface git-search



To install latest AngularFire and Firebase for latest Angular CLI 7.x

# To install latest AngularFire and Firebase for latest Angular CLI 7.x
npm install firebase @angular/fire --save



To skip/avoid long path in terminal (shortcut)

# To skip/avoid long path in terminal (shortcut)
prompt $$



Thanks for reading this post!

I hope this article is informative and helpful in some way. If it is, please like and share this article. Follow me on Twitter | LinkedIn for more related tips and posts.

Happy learning!




Source link