A fully functional Instagram clone written in Flutter using Firebase / Firestore

Overview

Fluttergram

A working Instagram clone written in Flutter using Firebase / Firestore

Demo

Download the release APK to try out Fluttergram

I update Fluttergram with new features and bugs fixes, but the apk may be behind master. Take a look at the changelog to see the most recent additions to the apk.

Features

  • Custom photo feed based on who you follow (using firebase cloud functions)
  • Post photo posts from camera or gallery
    • Like posts
    • Comment on posts
      • View all comments on a post
  • Search for users
  • Profile Pages
    • Follow / Unfollow Users
    • Change image view from grid layout to feed layout
    • Add your own bio
  • Activity Feed showing recent likes / comments of your posts + new followers

Screenshots

feed example upload photo example go to a profile from feed edit profile example comment and activity feed example

Dependencies

Getting started

1. Setup Flutter

2. Clone the repo

$ git clone https://github.com/mdanics/fluttergram.git
$ cd fluttergram/

3. Setup the firebase app

  1. You'll need to create a Firebase instance. Follow the instructions at https://console.firebase.google.com.
  2. Once your Firebase instance is created, you'll need to enable Google authentication.
  • Go to the Firebase Console for your new instance.
  • Click "Authentication" in the left-hand menu
  • Click the "sign-in method" tab
  • Click "Google" and enable it
  1. Create Cloud Functions (to make the Feed work)
  • Create a new firebase project with firebase init
  • Copy this project's functions/lib/index.js to your firebase project's functions/index.js
  • Push the function getFeed with firebase deploy --only functions In the output, you'll see the getFeed URL, copy that.
  • Replace the url in the _getFeed function in feed.dart with your cloud function url from the previous step.

If this does not work and you get the error Error: Error parsing triggers: Cannot find module './notificationHandler' Try following these steps. If you are still unable to get it to work please open a new issue.

You may need to create the neccessary index by running firebase functions:log and then clicking the link

If you are getting no errors, but an empty feed You must post photos or follow users with posts as the getFeed function only returns your own posts & posts from people you follow.

  1. Enable the Firebase Database
  • Go to the Firebase Console
  • Click "Database" in the left-hand menu
  • Click the Cloudstore "Create Database" button
  • Select "Start in test mode" and "Enable"
  1. (skip if not running on Android)
  • Create an app within your Firebase instance for Android, with package name com.yourcompany.news
  • Run the following command to get your SHA-1 key:
keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore
  • In the Firebase console, in the settings of your Android app, add your SHA-1 key by clicking "Add Fingerprint".
  • Follow instructions to download google-services.json
  • place google-services.json into /android/app/.
  1. (skip if not running on iOS)
  • Create an app within your Firebase instance for iOS, with your app package name
  • Follow instructions to download GoogleService-Info.plist
  • Open XCode, right click the Runner folder, select the "Add Files to 'Runner'" menu, and select the GoogleService-Info.plist file to add it to /ios/Runner in XCode
  • Open /ios/Runner/Info.plist in a text editor. Locate the CFBundleURLSchemes key. The second item in the array value of this key is specific to the Firebase instance. Replace it with the value for REVERSED_CLIENT_ID from GoogleService-Info.plist

Double check install instructions for both

What's Next?

  • Notificaitons for likes, comments, follows, etc
  • Animations (heart when liking image) (#77)
  • Improve Caching of Profiles, Images, Etc.
  • Better post creation, add filters to your image
  • Custom Camera Implementation
  • Firebase Security Rules
  • Delete Posts
  • Direct Messaging
  • Stories
  • Clean up code
Comments
  • Cloud Functions Setup

    Cloud Functions Setup

    Following README.md

    firebase deploy --only functions

    === Deploying to 'fluttergramdemo'...

    i deploying functions i functions: ensuring necessary APIs are enabled... ✔ functions: all necessary APIs are enabled i functions: preparing functions directory for uploading...

    Error: Error parsing triggers: Cannot find module './notificationHandler'

    Try running "npm install" in your functions directory before deploying.


    cd functions && npm install npm WARN [email protected] requires a peer of firebase-admin@~6.0.0 but none is installed. You must install peer dependencies yourself.

    audited 4170 packages in 2.042s found 0 vulnerabilities


    firebase deploy --only functions

    === Deploying to 'fluttergramdemo'...

    i deploying functions i functions: ensuring necessary APIs are enabled... ✔ functions: all necessary APIs are enabled i functions: preparing functions directory for uploading...

    Error: Error parsing triggers: Cannot find module './notificationHandler'

    Try running "npm install" in your functions directory before deploying.

    Having trouble? Try firebase deploy --help

    opened by ScottYelich 49
  • No visible @interface for 'FIRInstanceID' declares the selector 'token'

    No visible @interface for 'FIRInstanceID' declares the selector 'token'

    build fails because getting error in FirebaseMessagingPlugin.m. the error is generated from line 176. here's the code on line 176:

    [_channel invokeMethod:@"onToken" arguments:[[FIRInstanceID instanceID] token]];

    using legacy system. any solutions? thanks.

    opened by jaynelim 17
  • [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] pls help

    [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] pls help

    I get this error message. I checked the getfeed url correctly. Where's the trouble?

    [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FormatException: Unexpected character (at line 2, character 1) E/flutter (20332): E/flutter (20332): ^ E/flutter (20332): E/flutter (20332): #0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1394:5) E/flutter (20332): #1 _ChunkedJsonParser.parseNumber (dart:convert-patch/convert_patch.dart:1261:9) E/flutter (20332): #2 _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:926:22) E/flutter (20332): #3 _parseJson (dart:convert-patch/convert_patch.dart:31:10) E/flutter (20332): #4 JsonDecoder.convert (dart:convert/json.dart:505:36) E/flutter (20332): #5 JsonCodec.decode (dart:convert/json.dart:153:41) E/flutter (20332): #6 jsonDecode (dart:convert/json.dart:96:10) E/flutter (20332): #7 _Feed._loadFeed (package:Fluttergram/feed.dart:68:7) E/flutter (20332): E/flutter (20332): #8 _Feed.initState (package:Fluttergram/feed.dart:20:10) E/flutter (20332): #9 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4640:58) E/flutter (20332): #10 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5) E/flutter (20332): #11 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #12 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18) E/flutter (20332): #13 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5830:14) E/flutter (20332): #14 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #15 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18) E/flutter (20332): #16 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16) E/flutter (20332): #17 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5) E/flutter (20332): #18 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4481:5) E/flutter (20332): #19 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5) E/flutter (20332): #20 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #21 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18) E/flutter (20332): #22 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5830:14) E/flutter (20332): #23 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #24 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18) E/flutter (20332): #25 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5830:14) E/flutter (20332): #26 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #27 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18) E/flutter (20332): #28 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16) E/flutter (20332): #29 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5) E/flutter (20332): #30 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4481:5) E/flutter (20332): #31 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5) E/flutter (20332): #32 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #33 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18) E/flutter (20332): #34 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16) E/flutter (20332): #35 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5) E/flutter (20332): #36 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4481:5) E/flutter (20332): #37 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5) E/flutter (20332): #38 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #39 Element.updateChild (package:flutter/src/widgets/framework.dart:3214:18) E/flutter (20332): #40 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4527:16) E/flutter (20332): #41 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:11) E/flutter (20332): #42 Element.rebuild (package:flutter/src/widgets/framework.dart:4218:5) E/flutter (20332): #43 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4481:5) E/flutter (20332): #44 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4666:11) E/flutter (20332): #45 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4476:5) E/flutter (20332): #46 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3446:14) E/flutter (20332): #47 Element.updateChild (package:flutt

    opened by asmglr 14
  • Stuck at login screen

    Stuck at login screen

    I was finally able to get everything to build correctly and was able to get fluttergram to launch in my simulator and on my physical device. Both locations prompted me to sign in with google, which I used an existing account and the authentication seemed to work correctly. I do see the new userid show up in my Firebase instance. But after that initial auth fluttergram appears to be frozen. I see the main splash page with the same "Sign in with Google" option, but I am unable to tap on that sign in anymore. Force close the app and launch it again and it goes directly to the frozen screen. Same exact results on using the simulator and my iphone. I'm honestly not sure where to start with this issue, any suggestions? Thank you!


    PNG image

    opened by jnash766 11
  • Google SignIn & Firebase Auth not working anymore after updating

    Google SignIn & Firebase Auth not working anymore after updating

    After updating flutter and some packages the Google SignIn is not working anymore. It seems that the package changed its procedure with the newest version.

    https://pub.dartlang.org/packages/firebase_auth/versions/0.8.4+2 https://github.com/flutter/flutter/issues/27133

    Should not be too difficult too update the code.

    Thank you and btw great project and good job!

    opened by kamami 11
  • getFeed.js returns no data : []

    getFeed.js returns no data : []

    Hi, this is awesome project. I've cloned it, follow steps, creates indexes. All pages are now working except the home page, which display data returned by getFeed.js. I've tried to see, in my browser with url, if something is returns : YES I have a result by empty one. But I have 3 posts from 2 different users.

    Any ideas ?

    Thanks

    opened by didiosn 10
  • Username textfield goes blank on the first try to register

    Username textfield goes blank on the first try to register

    Reproducing

    • Clean database users and authentications
    • Delete app from emulator
    • Run application
    • Login with google account
    • Write username
    • Press next or confirmation on keyboard
    • Username field will erase
    • Write again
    • Press next or confirmation on keyboard
    • Username will be accepted and you will be redirected

    Debug console: https://pastebin.com/XSe6RReT

    opened by GustavoContreiras 9
  • Improvements on startup and UI

    Improvements on startup and UI

    Edit: Links are broken and I don't recommend anymore this approach.

    • You can see changes here: https://github.com/GustavoContreiras/fluttergram/commits/master

    (Don't copy and paste, use it as a guide and make changes by yourself. I'm almost sure these commits have errors.)

    • How it is working: Main starts, then set timestamps true in firestore while is loading FluttergramApp. The pageController and _firebaseMessaging are global variables. The _userLocation and the googleSignIn status are get on initState of the HomePage and passed to the creation of the CurrentUser calling CurrentUser.signInWithGoogle(silently: true, userLocation: _userLocation). If is signed it calls it silently: true, if not, silently: false. Then the signInWithGoogle methods creates the CurrentUser.instance. After that the HomePage is rebuild with home screen (feed screen) and notifications are set:
    @override
      Widget build(BuildContext context) {
    
        print('[HomePage] [Build] START');
    
        if (CurrentUser.instance != null) {
    
          if (!_notificationsAreSet) _setUpNotifications();
    
          print('[HomePage] [Build] CurrentUser.instance != null');
          print('[HomePage] [Build] building home screen');
          return Scaffold( ........
        }
        print('[RootPage] [Build] CurrentUser.instance == null');
        print('[RootPage] [Build] building login screen, _loadingIcon: $_loadingIcon');
        return _buildLoginScreen();
      }
    
    factory CurrentUser._singletonConstructor({DocumentSnapshot documentSnapshot, String username, Address userLocation}) {
    
        // Creates from snapshot from document from database (any login that isnt the first)
        if (documentSnapshot != null) {
          print('[CurrentUser] [Constructor] creating from document snapshot');
    
          if (documentSnapshot.data != null) {
            print('[CurrentUser] [Constructor] documentSnapshot.data != null');
            return CurrentUser(
              bio: documentSnapshot.data['bio'] == null ? '' : documentSnapshot.data['bio'],
              displayName: documentSnapshot.data['displayName'],
              username: documentSnapshot.data['username'],
              id:  documentSnapshot.data['uid'],
              photoUrl: documentSnapshot.data['photoURL'],
              followers: documentSnapshot.data['followers'] == null ? new Map<dynamic, dynamic>() : documentSnapshot.data['followers'],
              following: documentSnapshot.data['following'] == null ? new Map<dynamic, dynamic>() : documentSnapshot.data['following'],
              address: userLocation
            );
          }
          else {
            print('[CurrentUser] [Constructor] documentSnapshot.data == null');
          }
        }
    
        // Creates from Google account
        if (googleSignIn.currentUser != null) {
          print('[CurrentUser] [Constructor] googleSignIn.currentUser != null');
          print('[CurrentUser] [Constructor] creating from Google');
          return CurrentUser(
            bio: '',
            displayName: googleSignIn.currentUser.displayName,
            username: username,
            id: googleSignIn.currentUser.id,
            photoUrl: googleSignIn.currentUser.photoUrl,
            followers: {},
            following: {googleSignIn.currentUser.id: true},
            address: userLocation
          );
        }
    
        return null; 
      }
    
     static signInWithGoogle({bool silently = false, @required Address userLocation}) async {
     
        FirebaseUser _firebaseUser;
        AuthCredential _authCredential;
        DocumentReference _firebaseUserDocRef;
        DocumentSnapshot _firebaseUserDocSnap;
        GoogleSignInAccount _googleSignInAcc;
    
        print('[CurrentUser] [SignInWithGoogle] START');
    
        print('[CurrentUser] [SignInWithGoogle] googleSignIn.currentUser: ${googleSignIn.currentUser}');
    
    
        // Attempts to sign in a previously authenticated user without interaction
        if (silently) {
          print('[CurrentUser] [SignInWithGoogle] [SignInSilently] start');
          _googleSignInAcc = await googleSignIn.signInSilently();
          print('[CurrentUser] [SignInWithGoogle] [SignInSilently] done');
        }
    
        // Waits for user to choose account to sign
        else {
          print('[CurrentUser] [SignInWithGoogle] [SignIn] start');
          _googleSignInAcc = await googleSignIn.signIn();
          print('[CurrentUser] [SignInWithGoogle] [SignIn] done');
        } ............
    
    • Created CurrentUser class in user.dart file that is a singleton with non-final variables that holds the user address and has methods to sign in, create the current user from google (first login) or from document (any other login), sign out and update informations.
    • Moved FirebaseAuth and GoogleSignIn and everything related to authentication and sign in to CurrentUser class.
    • Removed the "take a picture blank screen" (if you click on "+" button on bottom bar, it opens a dialog that with 3 option -> take a picture / choose from gallery / cancel).
    • Removed "create username screen" (username is generated with display name and random numbers on first login).
    • Removed unnecessary widgets when showing camera file thumbnail.
    • Turned many public methods and variables in private.
    • Added dialog when clicking on "3 dots icon" on top right of the image showing "edit post" / "delete post" / "cancel"
    • Imported circular_profile_avatar package to add border and elevation on CircleAvatar

    Main.dart overall: image

    User.dart overall: image

    Upload_page.dart overall: image

    Profile_page.dart overall: image

    Feed.dart overall: image

    Console startup: image

    Things to do:

    • Save image resolution after picking it so you know the orientation (portrait / landscape) to make the image post on feed list with the right size (the way it is working now, portrait pphotos are bigger then original instagram).

    Edit: sorry for broken links

    enhancement Cross-Platform 
    opened by GustavoContreiras 8
  • alert dialog box

    alert dialog box

    the argument type Context cant be assign to parameter type BuildContext error in alert dialog box

    return showDialog( context: context, //here error barrierDismissible: false, // user must tap button!

    opened by mishubham 8
  • dependencies spec still valid?

    dependencies spec still valid?

    I am having trouble trying to get the dependencies to work... looks like http is the start of the mess, but then it moves on to things like:

    Running "flutter packages get" in fluttergram...
    Because cached_network_image >=0.4.1 <0.4.2 depends on flutter_cache_manager ^0.1.1 and cached_network_image >=0.4.0 <0.4.1 depends on flutter_cache_manager ^0.1.0, cached_network_image >=0.4.0 <0.4.2 requires flutter_cache_manager ^0.1.0. And because cached_network_image >=0.4.2 depends on flutter_cache_manager ^0.1.2 which depends on http ^0.11.3+14, cached_network_image >=0.4.0 requires http ^0.11.3+14. So, because Fluttergram depends on both cached_network_image ^0.4.0 and http ^0.12.0, version solving failed.

    pub get failed (1)

    opened by ScottYelich 8
  • [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.

    [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.

    I have set this up in Firebase etc, and I can see GoogleSignInAccount user = googleSignIn.currentUser; has user information

    However this function is not working

    factory User.fromDocument(DocumentSnapshot doc) {
        return User(
          email: doc.data()['email'],
          username: doc.data()['username'],
          photoUrl: doc.data()['photoUrl'],
          id: doc.id,
          displayName: doc.data()['displayName'],
          bio: doc.data()['bio'],
          followers: doc.data()['followers'],
          following: doc.data()['following'],
        );
      }
    
    E/flutter (28234): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
    E/flutter (28234): Receiver: null
    E/flutter (28234): Tried calling: []("email")
    E/flutter (28234): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
    E/flutter (28234): #1      new User.fromDocument (package:Fluttergram/models/user.dart:25:24)
    E/flutter (28234): #2      tryCreateUserRecord (package:Fluttergram/main.dart:144:27)
    E/flutter (28234): <asynchronous suspension>
    E/flutter (28234): #3      _ensureLoggedIn (package:Fluttergram/main.dart:40:5)
    E/flutter (28234): <asynchronous suspension>
    E/flutter (28234): #4      _HomePageState.login (package:Fluttergram/main.dart:296:5)
    E/flutter (28234): <asynchronous suspension>
    E/flutter (28234): 
    E/flutter (28234): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
    E/flutter (28234): Receiver: null
    E/flutter (28234): Tried calling: []("email")
    E/flutter (28234): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
    E/flutter (28234): #1      new User.fromDocument (package:Fluttergram/models/user.dart:25:24)
    E/flutter (28234): #2      tryCreateUserRecord (package:Fluttergram/main.dart:144:27)
    E/flutter (28234): <asynchronous suspension>
    E/flutter (28234): #3      _silentLogin (package:Fluttergram/main.dart:63:5)
    E/flutter (28234): <asynchronous suspension>
    E/flutter (28234): #4      _HomePageState.silentLogin (package:Fluttergram/main.dart:310:5)
    E/flutter (28234): <asynchronous suspension>
    E/flutter (28234): 
    
    opened by SimonBurfield 7
  • src/notificationHandler.ts(24,75): error TS2503: Cannot find namespace 'FirebaseFirestore'.

    src/notificationHandler.ts(24,75): error TS2503: Cannot find namespace 'FirebaseFirestore'.

    I have spent the last hour trying to get this to run, following the other issue reports and now I get:

    I think firebase has changed? if I update notificationHandler.ts to use a lowercase firebase.firestore it compiles but then I get a package.json issue

    Running command: npm --prefix "$RESOURCE_DIR" run build
    
    > build
    > tsc --skipLibCheck
    
    src/notificationHandler.ts(24,75): error TS2503: Cannot find namespace 'FirebaseFirestore'.
    
    Error: functions predeploy error: Command terminated with non-zero exit code2
    
    opened by burf2000 0
  • Apple Sign in

    Apple Sign in

    I have tried to implement apple sign in as an authentication provider, am having an issues for 1 Not navigating to the next page 2. It seems is not fetching any data am requesting. Below is the code using apple_sign_in 0.1.0 from pub.dev

    Future<void> _ensureLoggedIn(BuildContext context) async {
      print('[_ensureLoggedIn] START');
    
      GoogleSignInAccount user = googleSignIn.currentUser;
      if (user == null) {
        print('[_ensureLoggedIn] user == null');
        print('[_ensureLoggedIn] [signInSilently] START');
        user = await googleSignIn.signInSilently();
        print('[_ensureLoggedIn] [signInSilently] DONE');
      }
    
      if (user == null) {
        print('[_ensureLoggedIn] user == null');
        print('[_ensureLoggedIn] [signIn] START');
        await googleSignIn.signIn().then((_) {
          tryCreateUserRecord(context);
        });
        print('[_ensureLoggedIn] [signIn] DONE');
      }
    
      if (await auth.currentUser() == null) {
    
        print('[_ensureLoggedIn] auth.currentUser() == null');
        print('[_ensureLoggedIn] [googleSignIn.currentUser.authentication] START');
    
    
        GoogleSignInAuthentication credentials = await googleSignIn.currentUser.authentication;
        final GoogleSignInAccount googleUser = await googleSignIn.signIn();
        final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
    
    print('[_ensureLoggedIn] [googleSignIn.currentUser.authentication] DONE');
        print('[_ensureLoggedIn] [signInWithGoogle] START');
      final AuthCredential credential = GoogleAuthProvider.getCredential(
          accessToken: googleAuth.accessToken,
          idToken: googleAuth.idToken,
        );
     return(await auth.signInWithCredential(credential)).user.uid;
      }
    print('[_ensureLoggedIn] DONE');
    }
    Future<void> _silentLogin(BuildContext context) async {
      GoogleSignInAccount user = googleSignIn.currentUser;
    if (user == null) {
        user = await googleSignIn.signInSilently();
        await tryCreateUserRecord(context);
      }
     if (await auth.currentUser() == null && user != null) {
        final GoogleSignInAccount googleUser = await googleSignIn.signIn();
        final GoogleSignInAuthentication googleAuth = await googleUser
            .authentication;
       final AuthCredential credential = GoogleAuthProvider.getCredential(
          accessToken: googleAuth.accessToken,
          idToken: googleAuth.idToken,
        );
        await auth.signInWithCredential(credential);
      }
    }
    
    // APPLE
    Future<void> signInWithApple(BuildContext context) async {
      final AuthorizationResult result = await AppleSignIn.performRequests([
        AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
      ]);
    switch (result.status) {
        case AuthorizationStatus.authorized:
     // Store user ID
          await FlutterSecureStorage()
              .write(key: "userId", value: result.credential.user);
           final AppleIdCredential _auth = result.credential;
          final OAuthProvider oAuthProvider = new OAuthProvider(providerId: "apple.com");
         final AuthCredential credential = oAuthProvider.getCredential(
            idToken: String.fromCharCodes(_auth.identityToken),
            accessToken: String.fromCharCodes(_auth.authorizationCode),
          );
     await auth.signInWithCredential(credential);
    // update the user information
          if (_auth.fullName != null) {
            auth.currentUser().then( (value) async {
              UserUpdateInfo user = UserUpdateInfo();
              user.displayName = "${_auth.fullName.givenName} ${_auth.fullName.familyName}";
              await value.updateProfile(user);
            });
          }
    
          break;
     case AuthorizationStatus.error:
          print("Sign In Failed ${result.error.localizedDescription}");
          break;
    case AuthorizationStatus.cancelled:
          print("User Cancelled");
          break;
      }
    }
    tryCreateUserRecord(BuildContext context) async {
      GoogleSignInAccount user = googleSignIn.currentUser;
      if (user == null) {
        return null;
      }
      DocumentSnapshot userRecord = await ref.document(user.id).get();
      if (userRecord.data == null) {
        // no user record exists, time to create
     String userName = await Navigator.push( context,
          // We'll create the SelectionScreen in the next step!
          MaterialPageRoute(
              builder: (context) => Center(
                    child: Scaffold(
                        appBar: AppBar(
                          leading: Container(),
                          title: Text('Fill out missing data',
                              style: TextStyle(
                                  color: Colors.black,
                                  fontWeight: FontWeight.bold)),
                          backgroundColor: Colors.white,
                        ),
                        body: ListView(
                          children: <Widget>[
                             Container(
                              child: CreateAccount(),
                            ),
                          ],
                        )),
                  )),
     );
     if (userName != null || userName.length != 0){
          ref.document(user.id).setData({
            "id": user.id,
            "username": userName,
            "photoUrl": user.photoUrl,
            "email": user.email,
            "displayName": user.displayName,
          });
        }
      }
     currentUserModel = User.fromDocument(userRecord);
    }
     and separate container for 
    AppleSignInButton(
                   type: ButtonType.signIn,
                    cornerRadius: 6.0,
                     onPressed: () async {
                    await signInWithApple( context );
                    Navigator.push (context ,MaterialPageRoute(
                        builder: (_) =>
                            HomePage()));
                  },
    
    

    Please any help or any light something on the codes would be appreciated. Thanks

    enhancement 
    opened by pojoba02 1
  • Architect insta_users collection for better performance

    Architect insta_users collection for better performance

    Firestore.instance.document("insta_users/$profileId").updateData({
          'followers.$currentUserId': true
          //firestore plugin doesnt support deleting, so it must be nulled / falsed
        });
    
        Firestore.instance.document("insta_users/$currentUserId").updateData({
          'following.$profileId': true
          //firestore plugin doesnt support deleting, so it must be nulled / falsed
    });
    

    If each user (document) of the "insta_users" collection had inners collections called "followers" and "followings" that contains a string with the id of the user you are following/being followed, you could delete them instead of setting null.

    I know this project wasn't designed for millions of users and probably you won't change it (because it needs to recode many things) but I think it's good to point this out.

    Edit: Or even better, you don't need a new inner collection, you could just keep a followersIds field that holds a List of String and a followingsIds field that holds a List of String too and everytime the list change you recreate it and send the entire list again.

    Anyway, I don't know if I'm right. Just thinking that this thing of setting null because you cant delete is a little weird.

    enhancement 
    opened by GustavoContreiras 1
  • User search just found results with display name

    User search just found results with display name

    Searched for a user called "Pendulum Pala" with username "pendulumpala". Typing: Pendulum -> found pendulum -> not found pendulumpala -> not found pendulum pala -> not found pendulum Pala -> not found Pendulum Pala -> found Pala -> found pala -> not found

    I'm gonna try to improve that search and then I come back here.

    enhancement Cross-Platform 
    opened by GustavoContreiras 2
Owner
Matthew Danics
Computer Science @ Western University
Matthew Danics
A fully-functional e commerce app made in Flutter using Firebase.

Smart Shop ??️ A fully-functional e commerce app made in Flutter using Firebase. How To Run This Project ??‍♂️ Clone the repository. Create project on

null 25 Sep 30, 2022
Flutter Instagram using Firebase Firestore with similar functions 🔥🔥🔥

Instagram Flutter Build an Instagram clone project using firebase/firestore with similar functions ?? ?? ?? Give a ⭐ ⭐ ⭐  if you like this ?? Features

HuongPT 30 Jan 4, 2023
A fully functional chat application built with Flutter and Stream

?? SpikeChat A fully functional chat application built with Flutter and Stream! ✅ Join the chat room (If you have the secret passcode hehe) ✅ Send tex

Ashton Jones 20 Apr 30, 2022
Full Stack Instagram Clone made with ❤ using Flutter & Firebase.

Instagram Clone Full Stack Instagram Clone made with ❤ using Flutter & Firebase. Click on the link below to view the Overview video by Tushar Khatri.

Tushar Khatri 7 Oct 22, 2022
Amir Khan 47 Jan 8, 2023
Instagram Clone with Flutter 3 and Firebase

Multiplatform App with Flutter 3 and Firebase. Support for android, iOS, Macos and Web. ?? Working on making the view more Responsive, and support for Windows and Linux

Debanshu Datta 16 Oct 13, 2022
Task management app with flutter, firebase firestore, and firebase auth

to_do_list A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Alvin Ferdian 2 Mar 3, 2022
This is a fully fledged Sudoku game written in Dart using Flutter.

This is a fully fledged Sudoku game written in Dart using Flutter.

Varun Shanbhag 56 Dec 29, 2022
A Completed Functional Flutter App - FindSeat (BLoC + Json API + Unit Test + Firebase Auth)

A Completed Functional Flutter App - FindSeat (BLoC + Json API + Unit Test + Firebase Auth) I. Introduction I’m Android Developer and I’m working in a

Khoa Hoang 1k Jan 6, 2023
A Completed Functional Flutter App - FindSeat (BLoC + Json API + Unit Test + Firebase Auth)

A Completed Functional Flutter App - FindSeat (BLoC + Json API + Unit Test + Firebase Auth) II. Showcase 2.1. Home In Home screen, it just simply load

Dominique Rwema Bagirishya 48 Dec 6, 2022
A mobile image uploader in which you can upload image to your personal gallery from either your camera or mobile gallery and it can detect your current geographic location and address using firebase firestore and storage.

Image Uploader In Flutter About It is an Image Uploader gallery which tracks your address from which you're uploading using Flutter and Image picker.

Prahen parija 6 Dec 20, 2022
A Flutter project to practice how to use Firebase Firestore

flutter_chatbot_interview A Flutter project to practice how to use Firebase Fire

Adonias Delmiro Dantas Neto 8 Oct 31, 2022
:star: Flutter-Firebase fully backend messaging app

Orgonet ChatApp ⭐ Flutter-Firebase fully backend messaging app I made a backend full messaging app using firebase **download the file named orgone tv2

Berke Can Pınar 5 Nov 18, 2022
Fully Functioning Chat App with Flutter & Firebase

flutterchat A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if t

Mahdi 3 Aug 26, 2022
A Full Functional Application made bY Flutter Bloc Architcture.

Description Front End Flutter Bloc Architecture Back End Node Js An application designed for making home rentals easier. Lets landlords post their hom

Abel Ashine 1 Nov 18, 2021
An expressive, functional, and full-featured server-side framework for Dart.

A framework and collection of packages for writing http servers, built on top of the shelf package. This framework is intended to reduce the technical

Marathon 45 Jun 25, 2022
Flutter app to track stocks for multiple users, using Cloud Firestore on the backend.

stock_tracker Flutter app to track stocks for multiple users, using Cloud Firestore on the backend. Overview I wrote this Flutter application as a mea

John 2 Sep 16, 2022
Fintech dashboard clone - Fintech Dashboard Clone Built With Flutter

Fintech Dashboard Clone This repository is based on converting the mockup below

null 77 Jan 7, 2023
A fully cross-platform wrap of the Matomo tracking client for Flutter, using the Matomo API.

A fully cross-platform wrap of the Matomo tracking client for Flutter, using the Matomo Tracking API.

Floating Dartists 12 Jan 8, 2023