├── .gitignore ├── .metadata ├── CHANGELOG.md ├── CODEOWNERS ├── LICENSE ├── README.md ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── generated_plugin_registrant.dart │ ├── main.dart │ └── streambuilder_test.dart ├── linux │ ├── .gitignore │ ├── CMakeLists.txt │ ├── flutter │ │ ├── CMakeLists.txt │ │ ├── generated_plugin_registrant.cc │ │ ├── generated_plugin_registrant.h │ │ └── generated_plugins.cmake │ ├── main.cc │ ├── my_application.cc │ └── my_application.h ├── macos │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ └── app_icon_64.png │ │ ├── Base.lproj │ │ └── MainMenu.xib │ │ ├── Configs │ │ ├── AppInfo.xcconfig │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── Warnings.xcconfig │ │ ├── DebugProfile.entitlements │ │ ├── Info.plist │ │ ├── MainFlutterWindow.swift │ │ └── Release.entitlements ├── pubspec.yaml └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ └── Icon-512.png │ ├── index.html │ └── manifest.json ├── lib ├── geoflutterfire2.dart └── src │ ├── collection.dart │ ├── geoflutterfire2.dart │ ├── models │ └── DistanceDocSnapshot.dart │ ├── point.dart │ └── util.dart ├── pubspec.lock └── pubspec.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 60bd88df915880d23877bfc1602e8ddcf4c4dd2a 8 | channel: beta 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.3.15 2 | * provide option to listen on source location stream which doesn't cause memory leaks, [fix from this PR](https://github.com/beerstorm-net/GeoFlutterFire2/pull/26) 3 | * upgrade dependencies 4 | 5 | ## 2.3.14 6 | * upgrade dependencies 7 | * fix for query results duplicate after 1250km as described in [this issue](https://github.com/beerstorm-net/GeoFlutterFire2/issues/13) 8 | 9 | ## 2.3.13 10 | * upgrade dependencies 11 | 12 | ## 2.3.12 13 | * upgrade dependencies 14 | 15 | ## 2.3.11 16 | * upgrade dependencies 17 | 18 | ## 2.3.10 19 | * upgrade dependencies 20 | 21 | ## 2.3.9 22 | * upgrade dependencies: cloud_firestore 23 | 24 | ## 2.3.8 25 | * upgrade dependencies: cloud_firestore 26 | 27 | ## 2.3.7 28 | * upgrade dependencies 29 | 30 | ## 2.3.6 31 | * upgrade dependencies: cloud_firestore 32 | 33 | ## 2.3.5 34 | * upgrade dependencies: cloud_firestore 35 | 36 | ## 2.3.4 37 | * upgrade dependencies: cloud_firestore 38 | 39 | ## 2.3.3 40 | * upgrade dependencies: cloud_firestore 41 | 42 | ## 2.3.2 43 | * upgrade dependencies 44 | 45 | ## 2.3.1 46 | * upgrade dependencies 47 | 48 | ## 2.3.0 49 | * upgraded dependencies aligned with Flutter2 50 | * added Null safety 51 | * increment major version 52 | 53 | ## 2.2.4 54 | * update README 55 | * upgraded dependencies aligned with Flutter2 56 | 57 | ## 2.2.3 58 | * updates for pub analysis feedback 59 | * upgraded dependencies aligned with Flutter2 60 | 61 | ## 2.2.2 62 | * upgraded dependencies aligned with Flutter2 63 | * added Null safety 64 | * publish new package from forked project 65 | 66 | ## 2.1.0 67 | * fixed breaking changes 68 | * would not be able to access data using `doc.data['distance']` anymore 69 | 70 | ## 2.0.3+8 71 | * upgraded dependencies 72 | * fix for iOS build errors 73 | * fixes for breaking changes from 2.0.3 for stream builders 74 | * added a bug-fix for supporting stream builders 75 | 76 | ## 2.0.2 77 | * added support for filtering documents strictly/easily with respect to radius 78 | 79 | ## 2.0.1+1 80 | * bumped up the versions of kotlin-plugin and gradle. 81 | * Support for GeoPoints nested inside the firestore document 82 | 83 | ## 2.0.0 84 | * **Breaking change**. Migrate from the deprecated original Android Support 85 | Library to AndroidX. This shouldn't result in any functional changes, but it 86 | requires any Android apps using this plugin to [also 87 | migrate](https://developer.android.com/jetpack/androidx/migrate) if they're 88 | using the original support library. 89 | * reverted to flutter stable channel from master. 90 | 91 | ## 1.0.2 92 | * Refactored code to adhere to best practices(again) 93 | 94 | ## 1.0.1 95 | * Refactored code to adhere to best practices 96 | 97 | ## 1.0.0 98 | * Initial Release 99 | 100 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @zeusbaba 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Beerstorm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GeoFlutterFire2 :earth_africa: 2 | 3 | **NB! `GeoFlutterFire2` is the revisited & updated version of [GeoFlutterFire](https://github.com/DarshanGowda0/GeoFlutterFire)** 4 | 5 | GeoFlutterFire is an open-source library that allows you to store and query a set of keys based on their geographic location. At its heart, GeoFlutterFire simply stores locations with string keys. Its main benefit, however, is the possibility of retrieving only those keys within a given geographic area - all in realtime. 6 | 7 | GeoFlutterFire uses the Firebase Firestore Database for data storage, allowing query results to be updated in realtime as they change. GeoFlutterFire selectively loads only the data near certain locations, keeping your applications light and responsive, even with extremely large datasets. 8 | 9 | GeoFlutterFire is designed as a lightweight add-on to cloud_firestore plugin. To keep things simple, GeoFlutterFire stores data in its own format within your Firestore database. This allows your existing data format and Security Rules to remain unchanged while still providing you with an easy solution for geo queries. 10 | 11 | Heavily influenced by [GeoFireX](https://github.com/codediodeio/geofirex) :fire::fire: from [Jeff Delaney](https://github.com/codediodeio) :sunglasses: 12 | 13 | :tv: Checkout this amazing tutorial on [fireship](https://fireship.io/lessons/flutter-realtime-geolocation-firebase/) by Jeff, featuring the plugin!! 14 | 15 | 16 | ## Getting Started 17 | 18 | You should ensure that you add GeoFlutterFire as a dependency in your flutter project. 19 | 20 | ```yaml 21 | dependencies: 22 | geoflutterfire2: 23 | ``` 24 | 25 | You can also reference the git repo directly if you want: 26 | 27 | ```yaml 28 | dependencies: 29 | geoflutterfire2: 30 | git: git://github.com/beerstorm-net/GeoFlutterFire2.git 31 | ``` 32 | 33 | You should then run `flutter pub get` or update your packages in IntelliJ. 34 | 35 | ## Example 36 | 37 | There is a detailed example project in the `example` folder. Check that out or keep reading! 38 | 39 | ## Initialize 40 | 41 | You need a firebase project with [Firestore](https://pub.dartlang.org/packages/cloud_firestore) setup. 42 | 43 | ``` 44 | import 'package:geoflutterfire2/geoflutterfire2.dart'; 45 | import 'package:cloud_firestore/cloud_firestore.dart'; 46 | 47 | // Init firestore and geoFlutterFire 48 | final geo = GeoFlutterFire(); 49 | final _firestore = FirebaseFirestore.instance; 50 | ``` 51 | 52 | ## Writing Geo data 53 | 54 | Add geo data to your firestore document using `GeoFirePoint` 55 | 56 | ``` 57 | GeoFirePoint myLocation = geo.point(latitude: 12.960632, longitude: 77.641603); 58 | ``` 59 | 60 | Next, add the GeoFirePoint to you document using Firestore's add method 61 | 62 | ``` 63 | _firestore 64 | .collection('locations') 65 | .add({'name': 'random name', 'position': myLocation.data}); 66 | ``` 67 | 68 | Calling `geoFirePoint.data` returns an object that contains a [geohash string](https://www.movable-type.co.uk/scripts/geohash.html) and a [Firestore GeoPoint](https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/GeoPoint). It should look like this in your database. You can name the object whatever you want and even save multiple points on a single document. 69 | 70 | ![](https://firebasestorage.googleapis.com/v0/b/geo-test-c92e4.appspot.com/o/point1.png?alt=media&token=0c833700-3dbd-476a-99a9-41c1143dbe97) 71 | 72 | ## Query Geo data 73 | > **Warning** 74 | > Querying locations creates 9 separated stream listeners on firestore. One for central geo hash and 8 surrounding it. 75 | > `within` function creates a convenient broadcast stream, if you need more than one subscriber for the locations. But it also causes 76 | > memory leak, because underlying stream listeners are not cancelled when you cancel StreamSubscription from `within` method. 77 | > 78 | > It's much safer to use withinAsSingleStreamSubscription which you can cancel, and it will also cancel 9 underlying streams as well. 79 | 80 | To query a collection of documents with 50kms from a point 81 | 82 | ``` 83 | // Create a geoFirePoint 84 | GeoFirePoint center = geo.point(latitude: 12.960632, longitude: 77.641603); 85 | 86 | // get the collection reference or query 87 | var collectionReference = _firestore.collection('locations'); 88 | 89 | double radius = 50; 90 | String field = 'position'; 91 | 92 | Stream> stream = geo.collection(collectionRef: collectionReference) 93 | .within(center: center, radius: radius, field: field); 94 | ``` 95 | 96 | The within function returns a Stream of the list of DocumentSnapshot data, plus some useful metadata like distance from the centerpoint. 97 | 98 | ``` 99 | stream.listen((List documentList) { 100 | // doSomething() 101 | }); 102 | ``` 103 | 104 | You now have a realtime stream of data to visualize on a map. 105 | ![](https://firebasestorage.googleapis.com/v0/b/geoflutterfire.appspot.com/o/geflutterfire.gif?alt=media&token=8dc3aa9c-ee68-4dfe-9093-c3c1c48979dc) 106 | 107 | ## :notebook: API 108 | 109 | ### `collection(collectionRef: CollectionReference)` 110 | 111 | Creates a GeoCollectionRef which can be used to make geo queries, alternatively can also be used to write data just like firestore's add / set functionality. 112 | 113 | Example: 114 | 115 | ``` 116 | // Collection ref 117 | // var collectionReference = _firestore.collection('locations').where('city', isEqualTo: 'bangalore'); 118 | var collectionReference = _firestore.collection('locations'); 119 | var geoRef = geo.collection(collectionRef: collectionReference); 120 | ``` 121 | 122 | Note: collectionReference can be of type CollectionReference or Query 123 | 124 | #### Performing Geo-Queries 125 | 126 | `geoRef.within(center: GeoFirePoint, radius: double, field: String, {strictMode: bool})` 127 | 128 | Query the parent Firestore collection by geographic distance. It will return documents that exist within X kilometers of the center-point. 129 | `field` supports nested objects in the firestore document. 130 | 131 | **Note:** Use optional parameter `strictMode = true` to filter the documents strictly within the bound of given radius. 132 | 133 | Example: 134 | 135 | ``` 136 | // For GeoFirePoint stored at the root of the firestore document 137 | geoRef.within(center: centerGeoPoint, radius: 50, field: 'position', strictMode: true); 138 | 139 | // For GeoFirePoint nested in other objects of the firestore document 140 | geoRef.within(center: centerGeoPoint, radius: 50, field: 'address.location.position', strictMode: true); 141 | ``` 142 | 143 | Each `documentSnapshot.data()` also contains `distance` calculated on the query. 144 | 145 | **Returns:** `Stream>` 146 | 147 | #### Write Data 148 | 149 | Write data just like you would in Firestore 150 | 151 | `geoRef.add(data)` 152 | 153 | Or use one of the client's conveniece methods 154 | 155 | - `geoRef.setDoc(String id, var data, {bool merge})` - Set a document in the collection with an ID. 156 | - `geoRef.setPoint(String id, String field, double latitude, double longitude)`- Add a geohash to an existing doc 157 | 158 | #### Read Data 159 | 160 | In addition to Geo-Queries, you can also read the collection like you would normally in Firestore, but as an Observable 161 | 162 | - `geoRef.data()`- Stream of documentSnapshot 163 | - `geoRef.snapshot()`- Stream of Firestore QuerySnapshot 164 | 165 | ### `point(latitude: double, longitude: double)` 166 | 167 | Returns a GeoFirePoint allowing you to create geohashes, format data, and calculate relative distance. 168 | 169 | Example: `var point = geo.point(38, -119)` 170 | 171 | #### Getters 172 | 173 | - `point.hash` Returns a geohash string at precision 9 174 | - `point.geoPoint` Returns a Firestore GeoPoint 175 | - `point.data` Returns data object suitable for saving to the Firestore database 176 | 177 | #### Geo Calculations 178 | 179 | - `point.distance(latitude, longitude)` Haversine distance to a point 180 | 181 | ## :zap: Tips 182 | 183 | ### Scale to Massive Collections 184 | 185 | It's possible to build Firestore collections with billions of documents. One of the main motivations of this project was to make geoqueries possible on a queried subset of data. You can pass a Query instead of a CollectionReference into the collection(), then all geoqueries will be scoped with the constraints of that query. 186 | 187 | Note: This query requires a composite index, which you will be prompted to create with an error from Firestore on the first request. 188 | 189 | Example: 190 | 191 | ``` 192 | var queryRef = _firestore.collection('locations').where('city', isEqualTo: 'bangalore'); 193 | var stream = geo 194 | .collection(collectionRef: queryRef) 195 | .within(center: center, radius: rad, field: 'position'); 196 | ``` 197 | 198 | ### Usage of strictMode 199 | 200 | It's advisable to use `strictMode = false` for smaller radius to make use of documents from neighbouring hashes as well. 201 | 202 | As the radius increases to a large number, the neighbouring hash precisions fetch documents which would be considerably far from the radius bounds, hence its advisable to use `strictMode = true` for larger radius. 203 | 204 | **Note:** filtering for strictMode happens on client side, hence filtering at larger radius is at the expense of making unnecessary document reads. 205 | 206 | ### Make Dynamic Queries the RxDart Way 207 | 208 | ``` 209 | var radius = BehaviorSubject.seeded(1.0); 210 | var collectionReference = _firestore.collection('locations'); 211 | 212 | stream = radius.switchMap((rad) { 213 | return geo 214 | .collection(collectionRef: collectionReference) 215 | .within(center: center, radius: rad, field: 'position'); 216 | }); 217 | 218 | // Now update your query 219 | radius.add(25); 220 | ``` 221 | 222 | ### Limitations 223 | 224 | - range queries on multiple fields is not suppoerted by cloud_firestore at the moment, since this library already uses range query on `geohash` field, you cannot perform range queries with `GeoFireCollectionRef`. 225 | - `limit()` and `orderBy()` are not supported at the moment. `limit()` could be used to limit docs inside each hash individually which would result in running limit on all 9 hashes inside the specified radius. `orderBy()` is first run on `geohashes` in the library, hence appending `orderBy()` with another feild wouldn't produce expected results. Alternatively documents can be sorted on client side. 226 | 227 | ### Acknowledgements 228 | **NB! `GeoFlutterFire2` is a revisited and updated version of [GeoFlutterFire](https://github.com/DarshanGowda0/GeoFlutterFire)** 229 | The work originates from [GeoFlutterFire](https://github.com/DarshanGowda0/GeoFlutterFire) by Darshan Narayanaswamy 230 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # Visual Studio Code related 20 | .vscode/ 21 | 22 | # Flutter/Dart/Pub related 23 | **/doc/api/ 24 | .dart_tool/ 25 | .flutter-plugins 26 | .flutter-plugins-dependencies 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/flutter_export_environment.sh 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Generated.xcconfig 62 | **/ios/Flutter/app.flx 63 | **/ios/Flutter/app.zip 64 | **/ios/Flutter/flutter_assets/ 65 | **/ios/ServiceDefinitions.json 66 | **/ios/Runner/GeneratedPluginRegistrant.* 67 | 68 | # Exceptions to above rules. 69 | !**/ios/**/default.mode1v3 70 | !**/ios/**/default.mode2v3 71 | !**/ios/**/default.pbxuser 72 | !**/ios/**/default.perspectivev3 73 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 74 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 1407091bfb5bb535630d4d596541817737da8412 8 | channel: unknown 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # geoflutterfire_example 2 | 3 | Demonstrates how to use the geoflutterfire plugin. 4 | 5 | ```dart 6 | import 'package:flutter/material.dart'; 7 | import 'package:geoflutterfire/geoflutterfire.dart'; 8 | import 'package:cloud_firestore/cloud_firestore.dart'; 9 | import 'package:geoflutterfire/src/point.dart'; 10 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 11 | import 'package:rxdart/rxdart.dart'; 12 | 13 | void main() => runApp(MaterialApp( 14 | title: 'Geo Flutter Fire example', 15 | home: MyApp(), 16 | debugShowCheckedModeBanner: false, 17 | )); 18 | 19 | class MyApp extends StatefulWidget { 20 | @override 21 | _MyAppState createState() => _MyAppState(); 22 | } 23 | 24 | class _MyAppState extends State { 25 | GoogleMapController _mapController; 26 | TextEditingController _latitudeController, _longitudeController; 27 | 28 | // firestore init 29 | final _firestore = FirebaseFirestore.instance; 30 | Geoflutterfire geo; 31 | Stream> stream; 32 | var radius = BehaviorSubject(seedValue: 1.0); 33 | 34 | @override 35 | void initState() { 36 | super.initState(); 37 | _latitudeController = TextEditingController(); 38 | _longitudeController = TextEditingController(); 39 | 40 | geo = Geoflutterfire(); 41 | GeoFirePoint center = geo.point(latitude: 12.960632, longitude: 77.641603); 42 | stream = radius.switchMap((rad) { 43 | var collectionReference = _firestore.collection('locations'); 44 | // .where('name', isEqualTo: 'darshan'); 45 | return geo 46 | .collection(collectionRef: collectionReference) 47 | .within(center: center, radius: rad, field: 'position'); 48 | 49 | /* 50 | ****Example to specify nested object**** 51 | 52 | var collectionReference = _firestore.collection('nestedLocations'); 53 | // .where('name', isEqualTo: 'darshan'); 54 | return geo.collection(collectionRef: collectionReference).within( 55 | center: center, radius: rad, field: 'address.location.position'); 56 | 57 | */ 58 | }); 59 | } 60 | 61 | @override 62 | void dispose() { 63 | super.dispose(); 64 | radius.close(); 65 | } 66 | 67 | @override 68 | Widget build(BuildContext context) { 69 | return MaterialApp( 70 | home: Scaffold( 71 | appBar: AppBar( 72 | title: const Text('GeoFlutterFire'), 73 | actions: [ 74 | IconButton( 75 | onPressed: _mapController == null 76 | ? null 77 | : () { 78 | _showHome(); 79 | }, 80 | icon: Icon(Icons.home), 81 | ) 82 | ], 83 | ), 84 | body: Container( 85 | child: Column( 86 | crossAxisAlignment: CrossAxisAlignment.center, 87 | children: [ 88 | Center( 89 | child: Card( 90 | elevation: 4, 91 | margin: EdgeInsets.symmetric(vertical: 8), 92 | child: SizedBox( 93 | width: MediaQuery.of(context).size.width - 30, 94 | height: MediaQuery.of(context).size.height * (1 / 3), 95 | child: GoogleMap( 96 | onMapCreated: _onMapCreated, 97 | initialCameraPosition: const CameraPosition( 98 | target: LatLng(12.960632, 77.641603), 99 | zoom: 15.0, 100 | ), 101 | ), 102 | ), 103 | ), 104 | ), 105 | Padding( 106 | padding: const EdgeInsets.only(top: 8.0), 107 | child: Slider( 108 | min: 1, 109 | max: 200, 110 | divisions: 4, 111 | value: _value, 112 | label: _label, 113 | activeColor: Colors.blue, 114 | inactiveColor: Colors.blue.withOpacity(0.2), 115 | onChanged: (double value) => changed(value), 116 | ), 117 | ), 118 | Row( 119 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 120 | children: [ 121 | Container( 122 | width: 100, 123 | child: TextField( 124 | controller: _latitudeController, 125 | keyboardType: TextInputType.number, 126 | textInputAction: TextInputAction.next, 127 | decoration: InputDecoration( 128 | labelText: 'lat', 129 | border: OutlineInputBorder( 130 | borderRadius: BorderRadius.circular(8), 131 | )), 132 | ), 133 | ), 134 | Container( 135 | width: 100, 136 | child: TextField( 137 | controller: _longitudeController, 138 | keyboardType: TextInputType.number, 139 | decoration: InputDecoration( 140 | labelText: 'lng', 141 | border: OutlineInputBorder( 142 | borderRadius: BorderRadius.circular(8), 143 | )), 144 | ), 145 | ), 146 | MaterialButton( 147 | color: Colors.blue, 148 | onPressed: () { 149 | double lat = double.parse(_latitudeController.text); 150 | double lng = double.parse(_longitudeController.text); 151 | _addPoint(lat, lng); 152 | }, 153 | child: Text( 154 | 'ADD', 155 | style: TextStyle(color: Colors.white), 156 | ), 157 | ) 158 | ], 159 | ), 160 | MaterialButton( 161 | color: Colors.amber, 162 | child: Text( 163 | 'Add nested ', 164 | style: TextStyle(color: Colors.white), 165 | ), 166 | onPressed: () { 167 | double lat = double.parse(_latitudeController.text); 168 | double lng = double.parse(_longitudeController.text); 169 | _addNestedPoint(lat, lng); 170 | }, 171 | ) 172 | ], 173 | ), 174 | ), 175 | ), 176 | ); 177 | } 178 | 179 | void _onMapCreated(GoogleMapController controller) { 180 | setState(() { 181 | _mapController = controller; 182 | // _showHome(); 183 | //start listening after map is created 184 | stream.listen((List documentList) { 185 | _updateMarkers(documentList); 186 | }); 187 | }); 188 | } 189 | 190 | void _showHome() { 191 | _mapController.animateCamera(CameraUpdate.newCameraPosition( 192 | const CameraPosition( 193 | target: LatLng(12.960632, 77.641603), 194 | zoom: 15.0, 195 | ), 196 | )); 197 | } 198 | 199 | void _addPoint(double lat, double lng) { 200 | GeoFirePoint geoFirePoint = geo.point(latitude: lat, longitude: lng); 201 | _firestore 202 | .collection('locations') 203 | .add({'name': 'random name', 'position': geoFirePoint.data}).then((_) { 204 | print('added ${geoFirePoint.hash} successfully'); 205 | }); 206 | } 207 | 208 | //example to add geoFirePoint inside nested object 209 | void _addNestedPoint(double lat, double lng) { 210 | GeoFirePoint geoFirePoint = geo.point(latitude: lat, longitude: lng); 211 | _firestore.collection('nestedLocations').add({ 212 | 'name': 'random name', 213 | 'address': { 214 | 'location': {'position': geoFirePoint.data} 215 | } 216 | }).then((_) { 217 | print('added ${geoFirePoint.hash} successfully'); 218 | }); 219 | } 220 | 221 | void _addMarker(double lat, double lng) { 222 | var _marker = MarkerOptions( 223 | position: LatLng(lat, lng), 224 | icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueViolet), 225 | ); 226 | setState(() { 227 | _mapController.addMarker(_marker); 228 | }); 229 | } 230 | 231 | void _updateMarkers(List documentList) { 232 | documentList.forEach((DocumentSnapshot document) { 233 | GeoPoint point = document.data['position']['geopoint']; 234 | _addMarker(point.latitude, point.longitude); 235 | }); 236 | } 237 | 238 | double _value = 20.0; 239 | String _label = ''; 240 | 241 | changed(value) { 242 | setState(() { 243 | _value = value; 244 | _label = '${_value.toInt().toString()} kms'; 245 | _mapController.clearMarkers(); 246 | }); 247 | radius.add(value); 248 | } 249 | } 250 | ``` 251 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 30 29 | 30 | defaultConfig { 31 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 32 | applicationId "com.example.example" 33 | minSdkVersion 21 34 | targetSdkVersion 30 35 | versionCode flutterVersionCode.toInteger() 36 | versionName flutterVersionName 37 | } 38 | 39 | buildTypes { 40 | release { 41 | // TODO: Add your own signing config for the release build. 42 | // Signing with the debug keys for now, so `flutter run --release` works. 43 | signingConfig signingConfigs.debug 44 | } 45 | } 46 | } 47 | 48 | flutter { 49 | source '../..' 50 | } 51 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:4.1.0' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | INFOPLIST_FILE = Runner/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 297 | SWIFT_VERSION = 5.0; 298 | VERSIONING_SYSTEM = "apple-generic"; 299 | }; 300 | name = Profile; 301 | }; 302 | 97C147031CF9000F007C117D /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | ONLY_ACTIVE_ARCH = YES; 352 | SDKROOT = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | }; 355 | name = Debug; 356 | }; 357 | 97C147041CF9000F007C117D /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 381 | CLANG_WARN_STRICT_PROTOTYPES = YES; 382 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu99; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 394 | GCC_WARN_UNDECLARED_SELECTOR = YES; 395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 396 | GCC_WARN_UNUSED_FUNCTION = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 399 | MTL_ENABLE_DEBUG_INFO = NO; 400 | SDKROOT = iphoneos; 401 | SUPPORTED_PLATFORMS = iphoneos; 402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | VALIDATE_PRODUCT = YES; 405 | }; 406 | name = Release; 407 | }; 408 | 97C147061CF9000F007C117D /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 411 | buildSettings = { 412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 413 | CLANG_ENABLE_MODULES = YES; 414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 415 | ENABLE_BITCODE = NO; 416 | INFOPLIST_FILE = Runner/Info.plist; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 422 | SWIFT_VERSION = 5.0; 423 | VERSIONING_SYSTEM = "apple-generic"; 424 | }; 425 | name = Debug; 426 | }; 427 | 97C147071CF9000F007C117D /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | CLANG_ENABLE_MODULES = YES; 433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 434 | ENABLE_BITCODE = NO; 435 | INFOPLIST_FILE = Runner/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 440 | SWIFT_VERSION = 5.0; 441 | VERSIONING_SYSTEM = "apple-generic"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 97C147031CF9000F007C117D /* Debug */, 452 | 97C147041CF9000F007C117D /* Release */, 453 | 249021D3217E4FDB00AE95B9 /* Profile */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 97C147061CF9000F007C117D /* Debug */, 462 | 97C147071CF9000F007C117D /* Release */, 463 | 249021D4217E4FDB00AE95B9 /* Profile */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 471 | } 472 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/generated_plugin_registrant.dart: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // ignore_for_file: directives_ordering 6 | // ignore_for_file: lines_longer_than_80_chars 7 | // ignore_for_file: depend_on_referenced_packages 8 | 9 | import 'package:cloud_firestore_web/cloud_firestore_web.dart'; 10 | import 'package:firebase_core_web/firebase_core_web.dart'; 11 | 12 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 13 | 14 | // ignore: public_member_api_docs 15 | void registerPlugins(Registrar registrar) { 16 | FirebaseFirestoreWeb.registerWith(registrar); 17 | FirebaseCoreWeb.registerWith(registrar); 18 | registrar.registerMessageHandler(); 19 | } 20 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:geoflutterfire2/geoflutterfire2.dart'; 5 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 6 | import 'package:rxdart/rxdart.dart'; 7 | 8 | import 'streambuilder_test.dart'; 9 | 10 | void main() async { 11 | WidgetsFlutterBinding.ensureInitialized(); 12 | await Firebase.initializeApp(); 13 | runApp(MaterialApp( 14 | title: 'Geo Flutter Fire example', 15 | home: MyApp(), 16 | debugShowCheckedModeBanner: false, 17 | )); 18 | } 19 | 20 | class MyApp extends StatefulWidget { 21 | @override 22 | _MyAppState createState() => _MyAppState(); 23 | } 24 | 25 | class _MyAppState extends State { 26 | GoogleMapController _mapController; 27 | TextEditingController _latitudeController, _longitudeController; 28 | 29 | // firestore init 30 | final _firestore = FirebaseFirestore.instance; 31 | GeoFlutterFire geo; 32 | Stream> stream; 33 | final radius = BehaviorSubject.seeded(1.0); 34 | Map markers = {}; 35 | 36 | @override 37 | void initState() { 38 | super.initState(); 39 | _latitudeController = TextEditingController(); 40 | _longitudeController = TextEditingController(); 41 | 42 | geo = GeoFlutterFire(); 43 | GeoFirePoint center = geo.point(latitude: 12.960632, longitude: 77.641603); 44 | stream = radius.switchMap((rad) { 45 | var collectionReference = _firestore.collection('locations'); 46 | // .where('name', isEqualTo: 'darshan'); 47 | return geo.collection(collectionRef: collectionReference).within( 48 | center: center, radius: rad, field: 'position', strictMode: true); 49 | 50 | /* 51 | ****Example to specify nested object**** 52 | 53 | var collectionReference = _firestore.collection('nestedLocations'); 54 | // .where('name', isEqualTo: 'darshan'); 55 | return geo.collection(collectionRef: collectionReference).within( 56 | center: center, radius: rad, field: 'address.location.position'); 57 | 58 | */ 59 | }); 60 | } 61 | 62 | @override 63 | void dispose() { 64 | _latitudeController.dispose(); 65 | _longitudeController.dispose(); 66 | radius.close(); 67 | super.dispose(); 68 | } 69 | 70 | @override 71 | Widget build(BuildContext context) { 72 | final mediaQuery = MediaQuery.of(context); 73 | return MaterialApp( 74 | home: Scaffold( 75 | appBar: AppBar( 76 | title: const Text('GeoFlutterFire'), 77 | actions: [ 78 | IconButton( 79 | onPressed: _mapController == null 80 | ? null 81 | : () { 82 | _showHome(); 83 | }, 84 | icon: Icon(Icons.home), 85 | ) 86 | ], 87 | ), 88 | floatingActionButton: FloatingActionButton( 89 | onPressed: () { 90 | Navigator.of(context).push(MaterialPageRoute(builder: (context) { 91 | return StreamTestWidget(); 92 | })); 93 | }, 94 | child: Icon(Icons.navigate_next), 95 | ), 96 | body: Container( 97 | child: Column( 98 | crossAxisAlignment: CrossAxisAlignment.center, 99 | children: [ 100 | Center( 101 | child: Card( 102 | elevation: 4, 103 | margin: EdgeInsets.symmetric(vertical: 8), 104 | child: SizedBox( 105 | width: mediaQuery.size.width - 30, 106 | height: mediaQuery.size.height * (1 / 3), 107 | child: GoogleMap( 108 | onMapCreated: _onMapCreated, 109 | initialCameraPosition: const CameraPosition( 110 | target: LatLng(12.960632, 77.641603), 111 | zoom: 15.0, 112 | ), 113 | markers: Set.of(markers.values), 114 | ), 115 | ), 116 | ), 117 | ), 118 | Padding( 119 | padding: const EdgeInsets.only(top: 8.0), 120 | child: Slider( 121 | min: 1, 122 | max: 200, 123 | divisions: 4, 124 | value: _value, 125 | label: _label, 126 | activeColor: Colors.blue, 127 | inactiveColor: Colors.blue.withOpacity(0.2), 128 | onChanged: (double value) => changed(value), 129 | ), 130 | ), 131 | Row( 132 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 133 | children: [ 134 | Container( 135 | width: 100, 136 | child: TextField( 137 | controller: _latitudeController, 138 | keyboardType: TextInputType.number, 139 | textInputAction: TextInputAction.next, 140 | decoration: InputDecoration( 141 | labelText: 'lat', 142 | border: OutlineInputBorder( 143 | borderRadius: BorderRadius.circular(8), 144 | )), 145 | ), 146 | ), 147 | Container( 148 | width: 100, 149 | child: TextField( 150 | controller: _longitudeController, 151 | keyboardType: TextInputType.number, 152 | decoration: InputDecoration( 153 | labelText: 'lng', 154 | border: OutlineInputBorder( 155 | borderRadius: BorderRadius.circular(8), 156 | )), 157 | ), 158 | ), 159 | MaterialButton( 160 | color: Colors.blue, 161 | onPressed: () { 162 | final lat = double.parse(_latitudeController.text); 163 | final lng = double.parse(_longitudeController.text); 164 | _addPoint(lat, lng); 165 | }, 166 | child: const Text( 167 | 'ADD', 168 | style: TextStyle(color: Colors.white), 169 | ), 170 | ) 171 | ], 172 | ), 173 | MaterialButton( 174 | color: Colors.amber, 175 | child: const Text( 176 | 'Add nested ', 177 | style: TextStyle(color: Colors.white), 178 | ), 179 | onPressed: () { 180 | final lat = double.parse(_latitudeController.text); 181 | final lng = double.parse(_longitudeController.text); 182 | _addNestedPoint(lat, lng); 183 | }, 184 | ) 185 | ], 186 | ), 187 | ), 188 | ), 189 | ); 190 | } 191 | 192 | void _onMapCreated(GoogleMapController controller) { 193 | setState(() { 194 | _mapController = controller; 195 | // _showHome(); 196 | //start listening after map is created 197 | stream.listen((List documentList) { 198 | _updateMarkers(documentList); 199 | }); 200 | }); 201 | } 202 | 203 | void _showHome() { 204 | _mapController.animateCamera(CameraUpdate.newCameraPosition( 205 | const CameraPosition( 206 | target: LatLng(12.960632, 77.641603), 207 | zoom: 15.0, 208 | ), 209 | )); 210 | } 211 | 212 | void _addPoint(double lat, double lng) { 213 | GeoFirePoint geoFirePoint = geo.point(latitude: lat, longitude: lng); 214 | _firestore 215 | .collection('locations') 216 | .add({'name': 'random name', 'position': geoFirePoint.data}).then((_) { 217 | print('added ${geoFirePoint.hash} successfully'); 218 | }); 219 | } 220 | 221 | //example to add geoFirePoint inside nested object 222 | void _addNestedPoint(double lat, double lng) { 223 | GeoFirePoint geoFirePoint = geo.point(latitude: lat, longitude: lng); 224 | _firestore.collection('nestedLocations').add({ 225 | 'name': 'random name', 226 | 'address': { 227 | 'location': {'position': geoFirePoint.data} 228 | } 229 | }).then((_) { 230 | print('added ${geoFirePoint.hash} successfully'); 231 | }); 232 | } 233 | 234 | void _addMarker(double lat, double lng) { 235 | final id = MarkerId(lat.toString() + lng.toString()); 236 | final _marker = Marker( 237 | markerId: id, 238 | position: LatLng(lat, lng), 239 | icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueViolet), 240 | infoWindow: InfoWindow(title: 'latLng', snippet: '$lat,$lng'), 241 | ); 242 | setState(() { 243 | markers[id] = _marker; 244 | }); 245 | } 246 | 247 | void _updateMarkers(List documentList) { 248 | documentList.forEach((DocumentSnapshot document) { 249 | Map snapData = document.data(); 250 | final GeoPoint point = snapData['position']['geopoint']; 251 | _addMarker(point.latitude, point.longitude); 252 | }); 253 | } 254 | 255 | double _value = 20.0; 256 | String _label = ''; 257 | 258 | changed(value) { 259 | setState(() { 260 | _value = value; 261 | _label = '${_value.toInt().toString()} kms'; 262 | markers.clear(); 263 | }); 264 | radius.add(value); 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /example/lib/streambuilder_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:geoflutterfire2/geoflutterfire2.dart'; 4 | import 'package:rxdart/rxdart.dart'; 5 | 6 | class StreamTestWidget extends StatefulWidget { 7 | @override 8 | _StreamTestWidgetState createState() => _StreamTestWidgetState(); 9 | } 10 | 11 | class _StreamTestWidgetState extends State { 12 | Stream> stream; 13 | final _firestore = FirebaseFirestore.instance; 14 | final geo = GeoFlutterFire(); 15 | 16 | // ignore: close_sinks 17 | var radius = BehaviorSubject.seeded(1.0); 18 | 19 | @override 20 | void initState() { 21 | super.initState(); 22 | final center = geo.point(latitude: 12.960632, longitude: 77.641603); 23 | stream = radius.switchMap((rad) { 24 | var collectionReference = _firestore.collection('locations'); 25 | return geo.collection(collectionRef: collectionReference).within( 26 | center: center, radius: rad, field: 'position', strictMode: true); 27 | }); 28 | } 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return Scaffold( 33 | appBar: AppBar(), 34 | body: Column( 35 | children: [ 36 | StreamBuilder( 37 | stream: stream, 38 | builder: (BuildContext context, 39 | AsyncSnapshot> snapshots) { 40 | if (snapshots.connectionState == ConnectionState.active && 41 | snapshots.hasData) { 42 | print('data ${snapshots.data}'); 43 | return Container( 44 | height: MediaQuery.of(context).size.height * 2 / 3, 45 | child: ListView.builder( 46 | itemBuilder: (context, index) { 47 | final doc = snapshots.data[index]; 48 | Map data = doc.data(); 49 | print( 50 | 'doc with id ${doc.id} distance ${data['distance']}'); 51 | GeoPoint point = data['position']['geopoint']; 52 | return ListTile( 53 | title: Text( 54 | doc.id, 55 | style: const TextStyle(fontWeight: FontWeight.bold), 56 | ), 57 | subtitle: Text('${point.latitude}, ${point.longitude}'), 58 | trailing: Text( 59 | '${data['documentType'] == DocumentChangeType.added ? 'Added' : 'Modified'}'), 60 | ); 61 | }, 62 | itemCount: snapshots.data.length, 63 | ), 64 | ); 65 | } else { 66 | return const Center(child: CircularProgressIndicator()); 67 | } 68 | }, 69 | ), 70 | Padding( 71 | padding: const EdgeInsets.only(top: 8.0), 72 | child: Slider( 73 | min: 1, 74 | max: 200, 75 | divisions: 4, 76 | value: _value, 77 | label: _label, 78 | activeColor: Colors.blue, 79 | inactiveColor: Colors.blue.withOpacity(0.2), 80 | onChanged: (double value) => changed(value), 81 | ), 82 | ), 83 | ], 84 | ), 85 | ); 86 | } 87 | 88 | double _value = 20.0; 89 | String _label = ''; 90 | 91 | changed(value) { 92 | setState(() { 93 | _value = value; 94 | print(_value); 95 | _label = '${_value.toInt().toString()} kms'; 96 | }); 97 | radius.add(value); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /example/linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /example/linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(runner LANGUAGES CXX) 3 | 4 | set(BINARY_NAME "example") 5 | set(APPLICATION_ID "com.example.example") 6 | 7 | cmake_policy(SET CMP0063 NEW) 8 | 9 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 10 | 11 | # Configure build options. 12 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 13 | set(CMAKE_BUILD_TYPE "Debug" CACHE 14 | STRING "Flutter build mode" FORCE) 15 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 16 | "Debug" "Profile" "Release") 17 | endif() 18 | 19 | # Compilation settings that should be applied to most targets. 20 | function(APPLY_STANDARD_SETTINGS TARGET) 21 | target_compile_features(${TARGET} PUBLIC cxx_std_14) 22 | target_compile_options(${TARGET} PRIVATE -Wall -Werror) 23 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") 24 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") 25 | endfunction() 26 | 27 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 28 | 29 | # Flutter library and tool build rules. 30 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 31 | 32 | # System-level dependencies. 33 | find_package(PkgConfig REQUIRED) 34 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 35 | 36 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") 37 | 38 | # Application build 39 | add_executable(${BINARY_NAME} 40 | "main.cc" 41 | "my_application.cc" 42 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 43 | ) 44 | apply_standard_settings(${BINARY_NAME}) 45 | target_link_libraries(${BINARY_NAME} PRIVATE flutter) 46 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) 47 | add_dependencies(${BINARY_NAME} flutter_assemble) 48 | # Only the install-generated bundle's copy of the executable will launch 49 | # correctly, since the resources must in the right relative locations. To avoid 50 | # people trying to run the unbundled copy, put it in a subdirectory instead of 51 | # the default top-level location. 52 | set_target_properties(${BINARY_NAME} 53 | PROPERTIES 54 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" 55 | ) 56 | 57 | # Generated plugin build rules, which manage building the plugins and adding 58 | # them to the application. 59 | include(flutter/generated_plugins.cmake) 60 | 61 | 62 | # === Installation === 63 | # By default, "installing" just makes a relocatable bundle in the build 64 | # directory. 65 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") 66 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 67 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 68 | endif() 69 | 70 | # Start with a clean build bundle directory every time. 71 | install(CODE " 72 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") 73 | " COMPONENT Runtime) 74 | 75 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 76 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") 77 | 78 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 79 | COMPONENT Runtime) 80 | 81 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 82 | COMPONENT Runtime) 83 | 84 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 85 | COMPONENT Runtime) 86 | 87 | if(PLUGIN_BUNDLED_LIBRARIES) 88 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 89 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 90 | COMPONENT Runtime) 91 | endif() 92 | 93 | # Fully re-copy the assets directory on each build to avoid having stale files 94 | # from a previous install. 95 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 96 | install(CODE " 97 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 98 | " COMPONENT Runtime) 99 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 100 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 101 | 102 | # Install the AOT library on non-Debug builds only. 103 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") 104 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 105 | COMPONENT Runtime) 106 | endif() 107 | -------------------------------------------------------------------------------- /example/linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 4 | 5 | # Configuration provided via flutter tool. 6 | include(${EPHEMERAL_DIR}/generated_config.cmake) 7 | 8 | # TODO: Move the rest of this into files in ephemeral. See 9 | # https://github.com/flutter/flutter/issues/57146. 10 | 11 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 12 | # which isn't available in 3.10. 13 | function(list_prepend LIST_NAME PREFIX) 14 | set(NEW_LIST "") 15 | foreach(element ${${LIST_NAME}}) 16 | list(APPEND NEW_LIST "${PREFIX}${element}") 17 | endforeach(element) 18 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 19 | endfunction() 20 | 21 | # === Flutter Library === 22 | # System-level dependencies. 23 | find_package(PkgConfig REQUIRED) 24 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 25 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 26 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 27 | pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) 28 | pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma) 29 | 30 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 31 | 32 | # Published to parent scope for install step. 33 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 34 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 35 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 36 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 37 | 38 | list(APPEND FLUTTER_LIBRARY_HEADERS 39 | "fl_basic_message_channel.h" 40 | "fl_binary_codec.h" 41 | "fl_binary_messenger.h" 42 | "fl_dart_project.h" 43 | "fl_engine.h" 44 | "fl_json_message_codec.h" 45 | "fl_json_method_codec.h" 46 | "fl_message_codec.h" 47 | "fl_method_call.h" 48 | "fl_method_channel.h" 49 | "fl_method_codec.h" 50 | "fl_method_response.h" 51 | "fl_plugin_registrar.h" 52 | "fl_plugin_registry.h" 53 | "fl_standard_message_codec.h" 54 | "fl_standard_method_codec.h" 55 | "fl_string_codec.h" 56 | "fl_value.h" 57 | "fl_view.h" 58 | "flutter_linux.h" 59 | ) 60 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 61 | add_library(flutter INTERFACE) 62 | target_include_directories(flutter INTERFACE 63 | "${EPHEMERAL_DIR}" 64 | ) 65 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 66 | target_link_libraries(flutter INTERFACE 67 | PkgConfig::GTK 68 | PkgConfig::GLIB 69 | PkgConfig::GIO 70 | PkgConfig::BLKID 71 | PkgConfig::LZMA 72 | ) 73 | add_dependencies(flutter flutter_assemble) 74 | 75 | # === Flutter tool backend === 76 | # _phony_ is a non-existent file to force this command to run every time, 77 | # since currently there's no way to get a full input/output list from the 78 | # flutter tool. 79 | add_custom_command( 80 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 81 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 82 | COMMAND ${CMAKE_COMMAND} -E env 83 | ${FLUTTER_TOOL_ENVIRONMENT} 84 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 85 | linux-x64 ${CMAKE_BUILD_TYPE} 86 | VERBATIM 87 | ) 88 | add_custom_target(flutter_assemble DEPENDS 89 | "${FLUTTER_LIBRARY}" 90 | ${FLUTTER_LIBRARY_HEADERS} 91 | ) 92 | -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void fl_register_plugins(FlPluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | -------------------------------------------------------------------------------- /example/linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /example/linux/my_application.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | #include 4 | #ifdef GDK_WINDOWING_X11 5 | #include 6 | #endif 7 | 8 | #include "flutter/generated_plugin_registrant.h" 9 | 10 | struct _MyApplication { 11 | GtkApplication parent_instance; 12 | char** dart_entrypoint_arguments; 13 | }; 14 | 15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) 16 | 17 | // Implements GApplication::activate. 18 | static void my_application_activate(GApplication* application) { 19 | MyApplication* self = MY_APPLICATION(application); 20 | GtkWindow* window = 21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); 22 | 23 | // Use a header bar when running in GNOME as this is the common style used 24 | // by applications and is the setup most users will be using (e.g. Ubuntu 25 | // desktop). 26 | // If running on X and not using GNOME then just use a traditional title bar 27 | // in case the window manager does more exotic layout, e.g. tiling. 28 | // If running on Wayland assume the header bar will work (may need changing 29 | // if future cases occur). 30 | gboolean use_header_bar = TRUE; 31 | #ifdef GDK_WINDOWING_X11 32 | GdkScreen *screen = gtk_window_get_screen(window); 33 | if (GDK_IS_X11_SCREEN(screen)) { 34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); 35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) { 36 | use_header_bar = FALSE; 37 | } 38 | } 39 | #endif 40 | if (use_header_bar) { 41 | GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); 42 | gtk_widget_show(GTK_WIDGET(header_bar)); 43 | gtk_header_bar_set_title(header_bar, "example"); 44 | gtk_header_bar_set_show_close_button(header_bar, TRUE); 45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); 46 | } 47 | else { 48 | gtk_window_set_title(window, "example"); 49 | } 50 | 51 | gtk_window_set_default_size(window, 1280, 720); 52 | gtk_widget_show(GTK_WIDGET(window)); 53 | 54 | g_autoptr(FlDartProject) project = fl_dart_project_new(); 55 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); 56 | 57 | FlView* view = fl_view_new(project); 58 | gtk_widget_show(GTK_WIDGET(view)); 59 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); 60 | 61 | fl_register_plugins(FL_PLUGIN_REGISTRY(view)); 62 | 63 | gtk_widget_grab_focus(GTK_WIDGET(view)); 64 | } 65 | 66 | // Implements GApplication::local_command_line. 67 | static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) { 68 | MyApplication* self = MY_APPLICATION(application); 69 | // Strip out the first argument as it is the binary name. 70 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); 71 | 72 | g_autoptr(GError) error = nullptr; 73 | if (!g_application_register(application, nullptr, &error)) { 74 | g_warning("Failed to register: %s", error->message); 75 | *exit_status = 1; 76 | return TRUE; 77 | } 78 | 79 | g_application_activate(application); 80 | *exit_status = 0; 81 | 82 | return TRUE; 83 | } 84 | 85 | // Implements GObject::dispose. 86 | static void my_application_dispose(GObject *object) { 87 | MyApplication* self = MY_APPLICATION(object); 88 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); 89 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object); 90 | } 91 | 92 | static void my_application_class_init(MyApplicationClass* klass) { 93 | G_APPLICATION_CLASS(klass)->activate = my_application_activate; 94 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; 95 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose; 96 | } 97 | 98 | static void my_application_init(MyApplication* self) {} 99 | 100 | MyApplication* my_application_new() { 101 | return MY_APPLICATION(g_object_new(my_application_get_type(), 102 | "application-id", APPLICATION_ID, 103 | nullptr)); 104 | } 105 | -------------------------------------------------------------------------------- /example/linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import cloud_firestore 9 | import firebase_core 10 | 11 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 12 | FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) 13 | FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) 14 | } 15 | -------------------------------------------------------------------------------- /example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; 13 | buildPhases = ( 14 | 33CC111E2044C6BF0003C045 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = "Flutter Assemble"; 19 | productName = FLX; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 25 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 26 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 27 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 28 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 33CC111A2044C6BA0003C045; 37 | remoteInfo = FLX; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | 33CC110E2044A8840003C045 /* Bundle Framework */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | ); 49 | name = "Bundle Framework"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXCopyFilesBuildPhase section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 56 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; 57 | 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 59 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 60 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 61 | 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; 62 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; 63 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 64 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 65 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; 66 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 67 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 68 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 70 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 33CC10EA2044A3C60003C045 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 33BA886A226E78AF003329D5 /* Configs */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */, 88 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 89 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 90 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, 91 | ); 92 | path = Configs; 93 | sourceTree = ""; 94 | }; 95 | 33CC10E42044A3C60003C045 = { 96 | isa = PBXGroup; 97 | children = ( 98 | 33FAB671232836740065AC1E /* Runner */, 99 | 33CEB47122A05771004F2AC0 /* Flutter */, 100 | 33CC10EE2044A3C60003C045 /* Products */, 101 | D73912EC22F37F3D000D13A0 /* Frameworks */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 33CC10EE2044A3C60003C045 /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 33CC10ED2044A3C60003C045 /* example.app */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 33CC11242044D66E0003C045 /* Resources */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 33CC10F22044A3C60003C045 /* Assets.xcassets */, 117 | 33CC10F42044A3C60003C045 /* MainMenu.xib */, 118 | 33CC10F72044A3C60003C045 /* Info.plist */, 119 | ); 120 | name = Resources; 121 | path = ..; 122 | sourceTree = ""; 123 | }; 124 | 33CEB47122A05771004F2AC0 /* Flutter */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, 128 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 129 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 130 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, 131 | ); 132 | path = Flutter; 133 | sourceTree = ""; 134 | }; 135 | 33FAB671232836740065AC1E /* Runner */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */, 139 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, 140 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */, 141 | 33E51914231749380026EE4D /* Release.entitlements */, 142 | 33CC11242044D66E0003C045 /* Resources */, 143 | 33BA886A226E78AF003329D5 /* Configs */, 144 | ); 145 | path = Runner; 146 | sourceTree = ""; 147 | }; 148 | D73912EC22F37F3D000D13A0 /* Frameworks */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | ); 152 | name = Frameworks; 153 | sourceTree = ""; 154 | }; 155 | /* End PBXGroup section */ 156 | 157 | /* Begin PBXNativeTarget section */ 158 | 33CC10EC2044A3C60003C045 /* Runner */ = { 159 | isa = PBXNativeTarget; 160 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; 161 | buildPhases = ( 162 | 33CC10E92044A3C60003C045 /* Sources */, 163 | 33CC10EA2044A3C60003C045 /* Frameworks */, 164 | 33CC10EB2044A3C60003C045 /* Resources */, 165 | 33CC110E2044A8840003C045 /* Bundle Framework */, 166 | 3399D490228B24CF009A79C7 /* ShellScript */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | 33CC11202044C79F0003C045 /* PBXTargetDependency */, 172 | ); 173 | name = Runner; 174 | productName = Runner; 175 | productReference = 33CC10ED2044A3C60003C045 /* example.app */; 176 | productType = "com.apple.product-type.application"; 177 | }; 178 | /* End PBXNativeTarget section */ 179 | 180 | /* Begin PBXProject section */ 181 | 33CC10E52044A3C60003C045 /* Project object */ = { 182 | isa = PBXProject; 183 | attributes = { 184 | LastSwiftUpdateCheck = 0920; 185 | LastUpgradeCheck = 0930; 186 | ORGANIZATIONNAME = ""; 187 | TargetAttributes = { 188 | 33CC10EC2044A3C60003C045 = { 189 | CreatedOnToolsVersion = 9.2; 190 | LastSwiftMigration = 1100; 191 | ProvisioningStyle = Automatic; 192 | SystemCapabilities = { 193 | com.apple.Sandbox = { 194 | enabled = 1; 195 | }; 196 | }; 197 | }; 198 | 33CC111A2044C6BA0003C045 = { 199 | CreatedOnToolsVersion = 9.2; 200 | ProvisioningStyle = Manual; 201 | }; 202 | }; 203 | }; 204 | buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; 205 | compatibilityVersion = "Xcode 9.3"; 206 | developmentRegion = en; 207 | hasScannedForEncodings = 0; 208 | knownRegions = ( 209 | en, 210 | Base, 211 | ); 212 | mainGroup = 33CC10E42044A3C60003C045; 213 | productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; 214 | projectDirPath = ""; 215 | projectRoot = ""; 216 | targets = ( 217 | 33CC10EC2044A3C60003C045 /* Runner */, 218 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */, 219 | ); 220 | }; 221 | /* End PBXProject section */ 222 | 223 | /* Begin PBXResourcesBuildPhase section */ 224 | 33CC10EB2044A3C60003C045 /* Resources */ = { 225 | isa = PBXResourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 229 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXResourcesBuildPhase section */ 234 | 235 | /* Begin PBXShellScriptBuildPhase section */ 236 | 3399D490228B24CF009A79C7 /* ShellScript */ = { 237 | isa = PBXShellScriptBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | ); 241 | inputFileListPaths = ( 242 | ); 243 | inputPaths = ( 244 | ); 245 | outputFileListPaths = ( 246 | ); 247 | outputPaths = ( 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; 252 | }; 253 | 33CC111E2044C6BF0003C045 /* ShellScript */ = { 254 | isa = PBXShellScriptBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputFileListPaths = ( 259 | Flutter/ephemeral/FlutterInputs.xcfilelist, 260 | ); 261 | inputPaths = ( 262 | Flutter/ephemeral/tripwire, 263 | ); 264 | outputFileListPaths = ( 265 | Flutter/ephemeral/FlutterOutputs.xcfilelist, 266 | ); 267 | outputPaths = ( 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | shellPath = /bin/sh; 271 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; 272 | }; 273 | /* End PBXShellScriptBuildPhase section */ 274 | 275 | /* Begin PBXSourcesBuildPhase section */ 276 | 33CC10E92044A3C60003C045 /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 281 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, 282 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin PBXTargetDependency section */ 289 | 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { 290 | isa = PBXTargetDependency; 291 | target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; 292 | targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; 293 | }; 294 | /* End PBXTargetDependency section */ 295 | 296 | /* Begin PBXVariantGroup section */ 297 | 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { 298 | isa = PBXVariantGroup; 299 | children = ( 300 | 33CC10F52044A3C60003C045 /* Base */, 301 | ); 302 | name = MainMenu.xib; 303 | path = Runner; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXVariantGroup section */ 307 | 308 | /* Begin XCBuildConfiguration section */ 309 | 338D0CE9231458BD00FA5F75 /* Profile */ = { 310 | isa = XCBuildConfiguration; 311 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 316 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 317 | CLANG_CXX_LIBRARY = "libc++"; 318 | CLANG_ENABLE_MODULES = YES; 319 | CLANG_ENABLE_OBJC_ARC = YES; 320 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 326 | CLANG_WARN_EMPTY_BODY = YES; 327 | CLANG_WARN_ENUM_CONVERSION = YES; 328 | CLANG_WARN_INFINITE_RECURSION = YES; 329 | CLANG_WARN_INT_CONVERSION = YES; 330 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 335 | CODE_SIGN_IDENTITY = "-"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | GCC_C_LANGUAGE_STANDARD = gnu11; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | MACOSX_DEPLOYMENT_TARGET = 10.11; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | SDKROOT = macosx; 350 | SWIFT_COMPILATION_MODE = wholemodule; 351 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 352 | }; 353 | name = Profile; 354 | }; 355 | 338D0CEA231458BD00FA5F75 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 362 | CODE_SIGN_STYLE = Automatic; 363 | COMBINE_HIDPI_IMAGES = YES; 364 | INFOPLIST_FILE = Runner/Info.plist; 365 | LD_RUNPATH_SEARCH_PATHS = ( 366 | "$(inherited)", 367 | "@executable_path/../Frameworks", 368 | ); 369 | PROVISIONING_PROFILE_SPECIFIER = ""; 370 | SWIFT_VERSION = 5.0; 371 | }; 372 | name = Profile; 373 | }; 374 | 338D0CEB231458BD00FA5F75 /* Profile */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | CODE_SIGN_STYLE = Manual; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | }; 380 | name = Profile; 381 | }; 382 | 33CC10F92044A3C60003C045 /* Debug */ = { 383 | isa = XCBuildConfiguration; 384 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 385 | buildSettings = { 386 | ALWAYS_SEARCH_USER_PATHS = NO; 387 | CLANG_ANALYZER_NONNULL = YES; 388 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 390 | CLANG_CXX_LIBRARY = "libc++"; 391 | CLANG_ENABLE_MODULES = YES; 392 | CLANG_ENABLE_OBJC_ARC = YES; 393 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 394 | CLANG_WARN_BOOL_CONVERSION = YES; 395 | CLANG_WARN_CONSTANT_CONVERSION = YES; 396 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 397 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 398 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 399 | CLANG_WARN_EMPTY_BODY = YES; 400 | CLANG_WARN_ENUM_CONVERSION = YES; 401 | CLANG_WARN_INFINITE_RECURSION = YES; 402 | CLANG_WARN_INT_CONVERSION = YES; 403 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 404 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 405 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 406 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 407 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 408 | CODE_SIGN_IDENTITY = "-"; 409 | COPY_PHASE_STRIP = NO; 410 | DEBUG_INFORMATION_FORMAT = dwarf; 411 | ENABLE_STRICT_OBJC_MSGSEND = YES; 412 | ENABLE_TESTABILITY = YES; 413 | GCC_C_LANGUAGE_STANDARD = gnu11; 414 | GCC_DYNAMIC_NO_PIC = NO; 415 | GCC_NO_COMMON_BLOCKS = YES; 416 | GCC_OPTIMIZATION_LEVEL = 0; 417 | GCC_PREPROCESSOR_DEFINITIONS = ( 418 | "DEBUG=1", 419 | "$(inherited)", 420 | ); 421 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 422 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | MACOSX_DEPLOYMENT_TARGET = 10.11; 427 | MTL_ENABLE_DEBUG_INFO = YES; 428 | ONLY_ACTIVE_ARCH = YES; 429 | SDKROOT = macosx; 430 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 431 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 432 | }; 433 | name = Debug; 434 | }; 435 | 33CC10FA2044A3C60003C045 /* Release */ = { 436 | isa = XCBuildConfiguration; 437 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 438 | buildSettings = { 439 | ALWAYS_SEARCH_USER_PATHS = NO; 440 | CLANG_ANALYZER_NONNULL = YES; 441 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 442 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 443 | CLANG_CXX_LIBRARY = "libc++"; 444 | CLANG_ENABLE_MODULES = YES; 445 | CLANG_ENABLE_OBJC_ARC = YES; 446 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 447 | CLANG_WARN_BOOL_CONVERSION = YES; 448 | CLANG_WARN_CONSTANT_CONVERSION = YES; 449 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 450 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 451 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 452 | CLANG_WARN_EMPTY_BODY = YES; 453 | CLANG_WARN_ENUM_CONVERSION = YES; 454 | CLANG_WARN_INFINITE_RECURSION = YES; 455 | CLANG_WARN_INT_CONVERSION = YES; 456 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 457 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 458 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 459 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 460 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 461 | CODE_SIGN_IDENTITY = "-"; 462 | COPY_PHASE_STRIP = NO; 463 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 464 | ENABLE_NS_ASSERTIONS = NO; 465 | ENABLE_STRICT_OBJC_MSGSEND = YES; 466 | GCC_C_LANGUAGE_STANDARD = gnu11; 467 | GCC_NO_COMMON_BLOCKS = YES; 468 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 469 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | MACOSX_DEPLOYMENT_TARGET = 10.11; 474 | MTL_ENABLE_DEBUG_INFO = NO; 475 | SDKROOT = macosx; 476 | SWIFT_COMPILATION_MODE = wholemodule; 477 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 478 | }; 479 | name = Release; 480 | }; 481 | 33CC10FC2044A3C60003C045 /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 484 | buildSettings = { 485 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 486 | CLANG_ENABLE_MODULES = YES; 487 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 488 | CODE_SIGN_STYLE = Automatic; 489 | COMBINE_HIDPI_IMAGES = YES; 490 | INFOPLIST_FILE = Runner/Info.plist; 491 | LD_RUNPATH_SEARCH_PATHS = ( 492 | "$(inherited)", 493 | "@executable_path/../Frameworks", 494 | ); 495 | PROVISIONING_PROFILE_SPECIFIER = ""; 496 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 497 | SWIFT_VERSION = 5.0; 498 | }; 499 | name = Debug; 500 | }; 501 | 33CC10FD2044A3C60003C045 /* Release */ = { 502 | isa = XCBuildConfiguration; 503 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 504 | buildSettings = { 505 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 506 | CLANG_ENABLE_MODULES = YES; 507 | CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; 508 | CODE_SIGN_STYLE = Automatic; 509 | COMBINE_HIDPI_IMAGES = YES; 510 | INFOPLIST_FILE = Runner/Info.plist; 511 | LD_RUNPATH_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "@executable_path/../Frameworks", 514 | ); 515 | PROVISIONING_PROFILE_SPECIFIER = ""; 516 | SWIFT_VERSION = 5.0; 517 | }; 518 | name = Release; 519 | }; 520 | 33CC111C2044C6BA0003C045 /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | CODE_SIGN_STYLE = Manual; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | }; 526 | name = Debug; 527 | }; 528 | 33CC111D2044C6BA0003C045 /* Release */ = { 529 | isa = XCBuildConfiguration; 530 | buildSettings = { 531 | CODE_SIGN_STYLE = Automatic; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | }; 534 | name = Release; 535 | }; 536 | /* End XCBuildConfiguration section */ 537 | 538 | /* Begin XCConfigurationList section */ 539 | 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 33CC10F92044A3C60003C045 /* Debug */, 543 | 33CC10FA2044A3C60003C045 /* Release */, 544 | 338D0CE9231458BD00FA5F75 /* Profile */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { 550 | isa = XCConfigurationList; 551 | buildConfigurations = ( 552 | 33CC10FC2044A3C60003C045 /* Debug */, 553 | 33CC10FD2044A3C60003C045 /* Release */, 554 | 338D0CEA231458BD00FA5F75 /* Profile */, 555 | ); 556 | defaultConfigurationIsVisible = 0; 557 | defaultConfigurationName = Release; 558 | }; 559 | 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | 33CC111C2044C6BA0003C045 /* Debug */, 563 | 33CC111D2044C6BA0003C045 /* Release */, 564 | 338D0CEB231458BD00FA5F75 /* Profile */, 565 | ); 566 | defaultConfigurationIsVisible = 0; 567 | defaultConfigurationName = Release; 568 | }; 569 | /* End XCConfigurationList section */ 570 | }; 571 | rootObject = 33CC10E52044A3C60003C045 /* Project object */; 572 | } 573 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 71 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/macos/Runner/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: geoflutterfire_example 2 | description: Demonstrates how to use the Geoflutterfire2 plugin. 3 | publish_to: "none" 4 | 5 | environment: 6 | sdk: ">=2.1.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | 12 | # The following adds the Cupertino Icons font to your application. 13 | # Use with the CupertinoIcons class for iOS style icons. 14 | cupertino_icons: ^1.0.5 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | geoflutterfire2: 21 | path: ../ 22 | 23 | cloud_firestore: ^4.4.4 24 | google_maps_flutter: ^2.2.5 25 | 26 | # For information on the generic Dart part of this file, see the 27 | # following page: https://www.dartlang.org/tools/pub/pubspec 28 | 29 | # The following section is specific to Flutter. 30 | flutter: 31 | uses-material-design: true 32 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beerstorm-net/GeoFlutterFire2/366c1fac66e701ae264812f266c3d110604358ae/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | example 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /lib/geoflutterfire2.dart: -------------------------------------------------------------------------------- 1 | library geoflutterfire2; 2 | 3 | export 'src/collection.dart'; 4 | export 'src/geoflutterfire2.dart'; 5 | export 'src/point.dart'; 6 | -------------------------------------------------------------------------------- /lib/src/collection.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:cloud_firestore/cloud_firestore.dart'; 4 | import 'package:rxdart/rxdart.dart'; 5 | 6 | import 'models/DistanceDocSnapshot.dart'; 7 | import 'point.dart'; 8 | import 'util.dart'; 9 | 10 | class GeoFireCollectionRef { 11 | Query _collectionReference; 12 | Stream? _stream; 13 | 14 | GeoFireCollectionRef(this._collectionReference) { 15 | // : assert(_collectionReference != null) 16 | _stream = _createStream(_collectionReference)!.shareReplay(maxSize: 1); 17 | } 18 | 19 | /// return QuerySnapshot stream 20 | Stream? snapshot() { 21 | return _stream; 22 | } 23 | 24 | /// return the Document mapped to the [id] 25 | Stream> data(String id) { 26 | return _stream!.map((QuerySnapshot querySnapshot) { 27 | querySnapshot.docs.where((DocumentSnapshot documentSnapshot) { 28 | return documentSnapshot.id == id; 29 | }); 30 | return querySnapshot.docs; 31 | }); 32 | } 33 | 34 | /// add a document to collection with [data] 35 | Future add(Map data) { 36 | try { 37 | CollectionReference colRef = _collectionReference as CollectionReference; 38 | return colRef.add(data); 39 | } catch (e) { 40 | throw Exception( 41 | 'cannot call add on Query, use collection reference instead'); 42 | } 43 | } 44 | 45 | /// delete document with [id] from the collection 46 | Future delete(id) { 47 | try { 48 | CollectionReference colRef = _collectionReference as CollectionReference; 49 | return colRef.doc(id).delete(); 50 | } catch (e) { 51 | throw Exception( 52 | 'cannot call delete on Query, use collection reference instead'); 53 | } 54 | } 55 | 56 | /// create or update a document with [id], [merge] defines whether the document should overwrite 57 | Future setDoc(String id, var data, {bool merge = false}) { 58 | try { 59 | CollectionReference colRef = _collectionReference as CollectionReference; 60 | return colRef.doc(id).set(data, SetOptions(merge: merge)); 61 | } catch (e) { 62 | throw Exception( 63 | 'cannot call set on Query, use collection reference instead'); 64 | } 65 | } 66 | 67 | /// set a geo point with [latitude] and [longitude] using [field] as the object key to the document with [id] 68 | Future setPoint( 69 | String id, String field, double latitude, double longitude) { 70 | try { 71 | CollectionReference colRef = _collectionReference as CollectionReference; 72 | var point = GeoFirePoint(latitude, longitude).data; 73 | return colRef.doc(id).set({'$field': point}, SetOptions(merge: true)); 74 | } catch (e) { 75 | throw Exception( 76 | 'cannot call set on Query, use collection reference instead'); 77 | } 78 | } 79 | 80 | /// Create combined stream listeners for each geo hash around (including) central point. 81 | /// It creates 9 listeners and the hood. 82 | /// 83 | /// Returns [StreamController.stream] instance from rxdart, which is combined stream, 84 | /// for all 9 listeners. 85 | Stream> _buildQueryStream({ 86 | required GeoFirePoint center, 87 | required double radius, 88 | required String field, 89 | bool strictMode = false, 90 | }) { 91 | final precision = Util.setPrecision(radius); 92 | final centerHash = center.hash.substring(0, precision); 93 | final area = Set.from( 94 | GeoFirePoint.neighborsOf(hash: centerHash)..add(centerHash), 95 | ).toList(); 96 | 97 | Iterable>> queries = area.map((hash) { 98 | final tempQuery = _queryPoint(hash, field); 99 | return _createStream(tempQuery)!.map((QuerySnapshot querySnapshot) { 100 | return querySnapshot.docs 101 | .map((element) => DistanceDocSnapshot(element, null)) 102 | .toList(); 103 | }); 104 | }); 105 | 106 | Stream> mergedObservable = 107 | mergeObservable(queries); 108 | 109 | var filtered = mergedObservable.map((List list) { 110 | var mappedList = list.map((DistanceDocSnapshot distanceDocSnapshot) { 111 | // split and fetch geoPoint from the nested Map 112 | final fieldList = field.split('.'); 113 | Map snapData = 114 | distanceDocSnapshot.documentSnapshot.exists 115 | ? distanceDocSnapshot.documentSnapshot.data() as Map 116 | : Map(); 117 | var geoPointField = snapData[fieldList[0]]; 118 | //distanceDocSnapshot.documentSnapshot.data()![fieldList[0]]; 119 | if (fieldList.length > 1) { 120 | for (int i = 1; i < fieldList.length; i++) { 121 | geoPointField = geoPointField[fieldList[i]]; 122 | } 123 | } 124 | final GeoPoint geoPoint = geoPointField['geopoint']; 125 | distanceDocSnapshot.distance = 126 | center.distance(lat: geoPoint.latitude, lng: geoPoint.longitude); 127 | return distanceDocSnapshot; 128 | }); 129 | 130 | final filteredList = strictMode 131 | ? mappedList 132 | .where((DistanceDocSnapshot doc) => 133 | doc.distance! <= 134 | radius * 1.02 // buffer for edge distances; 135 | ) 136 | .toList() 137 | : mappedList.toList(); 138 | filteredList.sort((a, b) { 139 | final distA = a.distance!; 140 | final distB = b.distance!; 141 | final val = (distA * 1000).toInt() - (distB * 1000).toInt(); 142 | return val; 143 | }); 144 | return filteredList.map((element) => element.documentSnapshot).toList(); 145 | }); 146 | return filtered; 147 | } 148 | 149 | /// Query firestore documents based on geographic [radius] from geoFirePoint [center] 150 | /// [field] specifies the name of the key in the document 151 | /// returns merged stream as broadcast stream. 152 | /// 153 | /// Returns original stream from the underlying rxdart implementation, which 154 | /// could be safely cancelled without memory leaks. It's single stream subscription, 155 | /// so only single listener could be created at a time. 156 | /// 157 | /// This works the best if you have central point of listening for locations, 158 | /// not per widget. 159 | Stream> withinAsSingleStreamSubscription({ 160 | required GeoFirePoint center, 161 | required double radius, 162 | required String field, 163 | bool strictMode = false, 164 | }) { 165 | return _buildQueryStream( 166 | center: center, 167 | radius: radius, 168 | field: field, 169 | strictMode: strictMode, 170 | ); 171 | } 172 | 173 | /// Query firestore documents based on geographic [radius] from geoFirePoint [center] 174 | /// [field] specifies the name of the key in the document 175 | /// returns merged stream as broadcast stream. 176 | /// 177 | /// !WARNING! This causes memory leaks because under the hood rxdart StreamController 178 | /// never causes it's subscriptions to be cancelled. So, even you cancel stream 179 | /// subscription created from this method, under the hood listeners are still working. 180 | /// 181 | /// More at: https://github.com/dart-lang/sdk/issues/26686#issuecomment-225346901 182 | Stream> within({ 183 | required GeoFirePoint center, 184 | required double radius, 185 | required String field, 186 | bool strictMode = false, 187 | }) { 188 | return _buildQueryStream( 189 | center: center, 190 | radius: radius, 191 | field: field, 192 | strictMode: strictMode, 193 | ).asBroadcastStream(); 194 | } 195 | 196 | Stream> mergeObservable( 197 | Iterable>> queries) { 198 | Stream> mergedObservable = Rx.combineLatest( 199 | queries, (List> originalList) { 200 | final reducedList = []; 201 | originalList.forEach((t) { 202 | reducedList.addAll(t); 203 | }); 204 | return reducedList; 205 | }); 206 | return mergedObservable; 207 | } 208 | 209 | /// INTERNAL FUNCTIONS 210 | 211 | /// construct a query for the [geoHash] and [field] 212 | Query _queryPoint(String geoHash, String field) { 213 | final end = '$geoHash~'; 214 | final temp = _collectionReference; 215 | return temp.orderBy('$field.geohash').startAt([geoHash]).endAt([end]); 216 | } 217 | 218 | /// create an observable for [ref], [ref] can be [Query] or [CollectionReference] 219 | Stream? _createStream(var ref) { 220 | return ref.snapshots(); 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /lib/src/geoflutterfire2.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | import 'collection.dart'; 4 | import 'point.dart'; 5 | 6 | class GeoFlutterFire { 7 | GeoFlutterFire(); 8 | 9 | GeoFireCollectionRef collection({required Query collectionRef}) { 10 | return GeoFireCollectionRef(collectionRef); 11 | } 12 | 13 | GeoFirePoint point({required double latitude, required double longitude}) { 14 | return GeoFirePoint(latitude, longitude); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/src/models/DistanceDocSnapshot.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | class DistanceDocSnapshot { 4 | final DocumentSnapshot documentSnapshot; 5 | double? distance; 6 | 7 | DistanceDocSnapshot(this.documentSnapshot, this.distance); 8 | } 9 | -------------------------------------------------------------------------------- /lib/src/point.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | import 'util.dart'; 4 | 5 | class GeoFirePoint { 6 | static Util _util = Util(); 7 | double latitude, longitude; 8 | 9 | GeoFirePoint(this.latitude, this.longitude); 10 | 11 | /// return geographical distance between two Co-ordinates 12 | static double distanceBetween( 13 | {required Coordinates to, required Coordinates from}) { 14 | return Util.distance(to, from); 15 | } 16 | 17 | /// return neighboring geo-hashes of [hash] 18 | static List neighborsOf({required String hash}) { 19 | return _util.neighbors(hash); 20 | } 21 | 22 | /// return hash of [GeoFirePoint] 23 | String get hash { 24 | return _util.encode(this.latitude, this.longitude, 9); 25 | } 26 | 27 | /// return all neighbors of [GeoFirePoint] 28 | List get neighbors { 29 | return _util.neighbors(this.hash); 30 | } 31 | 32 | /// return [GeoPoint] of [GeoFirePoint] 33 | GeoPoint get geoPoint { 34 | return GeoPoint(this.latitude, this.longitude); 35 | } 36 | 37 | Coordinates get coords { 38 | return Coordinates(this.latitude, this.longitude); 39 | } 40 | 41 | /// return distance between [GeoFirePoint] and ([lat], [lng]) 42 | double distance({required double lat, required double lng}) { 43 | return distanceBetween(from: coords, to: Coordinates(lat, lng)); 44 | } 45 | 46 | get data { 47 | return {'geopoint': this.geoPoint, 'geohash': this.hash}; 48 | } 49 | 50 | /// haversine distance between [GeoFirePoint] and ([lat], [lng]) 51 | haversineDistance({required double lat, required double lng}) { 52 | return GeoFirePoint.distanceBetween( 53 | from: coords, to: Coordinates(lat, lng)); 54 | } 55 | } 56 | 57 | class Coordinates { 58 | double latitude; 59 | double longitude; 60 | 61 | Coordinates(this.latitude, this.longitude); 62 | } 63 | -------------------------------------------------------------------------------- /lib/src/util.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'point.dart'; 4 | 5 | class Util { 6 | static const BASE32_CODES = '0123456789bcdefghjkmnpqrstuvwxyz'; 7 | Map base32CodesDic = new Map(); 8 | 9 | Util() { 10 | for (var i = 0; i < BASE32_CODES.length; i++) { 11 | base32CodesDic.putIfAbsent(BASE32_CODES[i], () => i); 12 | } 13 | } 14 | 15 | var encodeAuto = 'auto'; 16 | 17 | /// 18 | /// Significant Figure Hash Length 19 | /// 20 | /// This is a quick and dirty lookup to figure out how long our hash 21 | /// should be in order to guarantee a certain amount of trailing 22 | /// significant figures. This was calculated by determining the error: 23 | /// 45/2^(n-1) where n is the number of bits for a latitude or 24 | /// longitude. Key is # of desired sig figs, value is minimum length of 25 | /// the geohash. 26 | /// @type Array 27 | // Desired sig figs: 0 1 2 3 4 5 6 7 8 9 10 28 | var sigfigHashLength = [0, 5, 7, 8, 11, 12, 13, 15, 16, 17, 18]; 29 | 30 | /// 31 | /// Encode 32 | /// Create a geohash from latitude and longitude 33 | /// that is 'number of chars' long 34 | String encode(var latitude, var longitude, var numberOfChars) { 35 | if (numberOfChars == encodeAuto) { 36 | if (latitude.runtimeType == double || longitude.runtimeType == double) { 37 | throw new Exception('string notation required for auto precision.'); 38 | } 39 | int decSigFigsLat = latitude.split('.')[1].length; 40 | int decSigFigsLon = longitude.split('.')[1].length; 41 | int numberOfSigFigs = max(decSigFigsLat, decSigFigsLon); 42 | numberOfChars = sigfigHashLength[numberOfSigFigs]; 43 | } else if (numberOfChars == null) { 44 | numberOfChars = 9; 45 | } 46 | 47 | var chars = [], bits = 0, bitsTotal = 0, hashValue = 0; 48 | double maxLat = 90, minLat = -90, maxLon = 180, minLon = -180, mid; 49 | 50 | while (chars.length < numberOfChars) { 51 | if (bitsTotal % 2 == 0) { 52 | mid = (maxLon + minLon) / 2; 53 | if (longitude > mid) { 54 | hashValue = (hashValue << 1) + 1; 55 | minLon = mid; 56 | } else { 57 | hashValue = (hashValue << 1) + 0; 58 | maxLon = mid; 59 | } 60 | } else { 61 | mid = (maxLat + minLat) / 2; 62 | if (latitude > mid) { 63 | hashValue = (hashValue << 1) + 1; 64 | minLat = mid; 65 | } else { 66 | hashValue = (hashValue << 1) + 0; 67 | maxLat = mid; 68 | } 69 | } 70 | 71 | bits++; 72 | bitsTotal++; 73 | if (bits == 5) { 74 | var code = BASE32_CODES[hashValue]; 75 | chars.add(code); 76 | bits = 0; 77 | hashValue = 0; 78 | } 79 | } 80 | 81 | return chars.join(''); 82 | } 83 | 84 | /// 85 | /// Decode Bounding box 86 | /// 87 | /// Decode a hashString into a bound box that matches it. 88 | /// Data returned in a List [minLat, minLon, maxLat, maxLon] 89 | List decodeBbox(String hashString) { 90 | var isLon = true; 91 | double maxLat = 90, minLat = -90, maxLon = 180, minLon = -180, mid; 92 | 93 | int? hashValue = 0; 94 | for (var i = 0, l = hashString.length; i < l; i++) { 95 | var code = hashString[i].toLowerCase(); 96 | hashValue = base32CodesDic[code]; 97 | 98 | for (var bits = 4; bits >= 0; bits--) { 99 | var bit = (hashValue! >> bits) & 1; 100 | if (isLon) { 101 | mid = (maxLon + minLon) / 2; 102 | if (bit == 1) { 103 | minLon = mid; 104 | } else { 105 | maxLon = mid; 106 | } 107 | } else { 108 | mid = (maxLat + minLat) / 2; 109 | if (bit == 1) { 110 | minLat = mid; 111 | } else { 112 | maxLat = mid; 113 | } 114 | } 115 | isLon = !isLon; 116 | } 117 | } 118 | return [minLat, minLon, maxLat, maxLon]; 119 | } 120 | 121 | /// 122 | /// Decode a [hashString] into a pair of latitude and longitude. 123 | /// A map is returned with keys 'latitude', 'longitude','latitudeError','longitudeError' 124 | Map decode(String hashString) { 125 | List bbox = decodeBbox(hashString); 126 | double lat = (bbox[0] + bbox[2]) / 2; 127 | double lon = (bbox[1] + bbox[3]) / 2; 128 | double latErr = bbox[2] - lat; 129 | double lonErr = bbox[3] - lon; 130 | return { 131 | 'latitude': lat, 132 | 'longitude': lon, 133 | 'latitudeError': latErr, 134 | 'longitudeError': lonErr, 135 | }; 136 | } 137 | 138 | /// 139 | /// Neighbor 140 | /// 141 | /// Find neighbor of a geohash string in certain direction. 142 | /// Direction is a two-element array, i.e. [1,0] means north, [-1,-1] means southwest. 143 | /// 144 | /// direction [lat, lon], i.e. 145 | /// [1,0] - north 146 | /// [1,1] - northeast 147 | String neighbor(String hashString, var direction) { 148 | var lonLat = decode(hashString); 149 | var neighborLat = 150 | lonLat['latitude']! + direction[0] * lonLat['latitudeError'] * 2; 151 | var neighborLon = 152 | lonLat['longitude']! + direction[1] * lonLat['longitudeError'] * 2; 153 | return encode(neighborLat, neighborLon, hashString.length); 154 | } 155 | 156 | /// 157 | /// Neighbors 158 | /// Returns all neighbors' hashstrings clockwise from north around to northwest 159 | /// 7 0 1 160 | /// 6 X 2 161 | /// 5 4 3 162 | List neighbors(String hashString) { 163 | int hashStringLength = hashString.length; 164 | var lonlat = decode(hashString); 165 | double? lat = lonlat['latitude']; 166 | double? lon = lonlat['longitude']; 167 | double latErr = lonlat['latitudeError']! * 2; 168 | double lonErr = lonlat['longitudeError']! * 2; 169 | 170 | var neighborLat, neighborLon; 171 | 172 | String encodeNeighbor(neighborLatDir, neighborLonDir) { 173 | neighborLat = lat! + neighborLatDir * latErr; 174 | neighborLon = lon! + neighborLonDir * lonErr; 175 | return encode(neighborLat, neighborLon, hashStringLength); 176 | } 177 | 178 | var neighborHashList = [ 179 | encodeNeighbor(1, 0), 180 | encodeNeighbor(1, 1), 181 | encodeNeighbor(0, 1), 182 | encodeNeighbor(-1, 1), 183 | encodeNeighbor(-1, 0), 184 | encodeNeighbor(-1, -1), 185 | encodeNeighbor(0, -1), 186 | encodeNeighbor(1, -1) 187 | ]; 188 | 189 | return neighborHashList; 190 | } 191 | 192 | static int setPrecision(double km) { 193 | /* 194 | * 1 ≤ 5,000km × 5,000km 195 | * 2 ≤ 1,250km × 625km 196 | * 3 ≤ 156km × 156km 197 | * 4 ≤ 39.1km × 19.5km 198 | * 5 ≤ 4.89km × 4.89km 199 | * 6 ≤ 1.22km × 0.61km 200 | * 7 ≤ 153m × 153m 201 | * 8 ≤ 38.2m × 19.1m 202 | * 9 ≤ 4.77m × 4.77m 203 | * 204 | */ 205 | 206 | if (km <= 0.00477) 207 | return 9; 208 | else if (km <= 0.0382) 209 | return 8; 210 | else if (km <= 0.153) 211 | return 7; 212 | else if (km <= 1.22) 213 | return 6; 214 | else if (km <= 4.89) 215 | return 5; 216 | else if (km <= 39.1) 217 | return 4; 218 | else if (km <= 156) 219 | return 3; 220 | else if (km <= 1250) 221 | return 2; 222 | else 223 | return 1; 224 | } 225 | 226 | static const double MAX_SUPPORTED_RADIUS = 8587; 227 | 228 | // Length of a degree latitude at the equator 229 | static const double METERS_PER_DEGREE_LATITUDE = 110574; 230 | 231 | // The equatorial circumference of the earth in meters 232 | static const double EARTH_MERIDIONAL_CIRCUMFERENCE = 40007860; 233 | 234 | // The equatorial radius of the earth in meters 235 | static const double EARTH_EQ_RADIUS = 6378137; 236 | 237 | // The meridional radius of the earth in meters 238 | static const double EARTH_POLAR_RADIUS = 6357852.3; 239 | 240 | /* The following value assumes a polar radius of 241 | * r_p = 6356752.3 242 | * and an equatorial radius of 243 | * r_e = 6378137 244 | * The value is calculated as e2 == (r_e^2 - r_p^2)/(r_e^2) 245 | * Use exact value to avoid rounding errors 246 | */ 247 | static const double EARTH_E2 = 0.00669447819799; 248 | 249 | // Cutoff for floating point calculations 250 | static const double EPSILON = 1e-12; 251 | 252 | static double distance(Coordinates location1, Coordinates location2) { 253 | return calcDistance(location1.latitude, location1.longitude, 254 | location2.latitude, location2.longitude); 255 | } 256 | 257 | static double calcDistance( 258 | double lat1, double long1, double lat2, double long2) { 259 | // Earth's mean radius in meters 260 | final double radius = (EARTH_EQ_RADIUS + EARTH_POLAR_RADIUS) / 2; 261 | double latDelta = _toRadians(lat1 - lat2); 262 | double lonDelta = _toRadians(long1 - long2); 263 | 264 | double a = (sin(latDelta / 2) * sin(latDelta / 2)) + 265 | (cos(_toRadians(lat1)) * 266 | cos(_toRadians(lat2)) * 267 | sin(lonDelta / 2) * 268 | sin(lonDelta / 2)); 269 | double distance = radius * 2 * atan2(sqrt(a), sqrt(1 - a)) / 1000; 270 | return double.parse(distance.toStringAsFixed(3)); 271 | } 272 | 273 | static double _toRadians(double num) { 274 | return num * (pi / 180.0); 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _flutterfire_internals: 5 | dependency: transitive 6 | description: 7 | name: _flutterfire_internals 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "1.0.17" 11 | async: 12 | dependency: transitive 13 | description: 14 | name: async 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.9.0" 18 | boolean_selector: 19 | dependency: transitive 20 | description: 21 | name: boolean_selector 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.1.0" 25 | characters: 26 | dependency: transitive 27 | description: 28 | name: characters 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.2.1" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.1" 39 | cloud_firestore: 40 | dependency: "direct main" 41 | description: 42 | name: cloud_firestore 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "4.4.4" 46 | cloud_firestore_platform_interface: 47 | dependency: transitive 48 | description: 49 | name: cloud_firestore_platform_interface 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "5.11.4" 53 | cloud_firestore_web: 54 | dependency: transitive 55 | description: 56 | name: cloud_firestore_web 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "3.3.4" 60 | collection: 61 | dependency: transitive 62 | description: 63 | name: collection 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.16.0" 67 | fake_async: 68 | dependency: transitive 69 | description: 70 | name: fake_async 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.3.1" 74 | firebase_core: 75 | dependency: transitive 76 | description: 77 | name: firebase_core 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "2.7.1" 81 | firebase_core_platform_interface: 82 | dependency: transitive 83 | description: 84 | name: firebase_core_platform_interface 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "4.5.3" 88 | firebase_core_web: 89 | dependency: transitive 90 | description: 91 | name: firebase_core_web 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "2.2.2" 95 | flutter: 96 | dependency: "direct main" 97 | description: flutter 98 | source: sdk 99 | version: "0.0.0" 100 | flutter_test: 101 | dependency: "direct dev" 102 | description: flutter 103 | source: sdk 104 | version: "0.0.0" 105 | flutter_web_plugins: 106 | dependency: transitive 107 | description: flutter 108 | source: sdk 109 | version: "0.0.0" 110 | js: 111 | dependency: transitive 112 | description: 113 | name: js 114 | url: "https://pub.dartlang.org" 115 | source: hosted 116 | version: "0.6.4" 117 | matcher: 118 | dependency: transitive 119 | description: 120 | name: matcher 121 | url: "https://pub.dartlang.org" 122 | source: hosted 123 | version: "0.12.12" 124 | material_color_utilities: 125 | dependency: transitive 126 | description: 127 | name: material_color_utilities 128 | url: "https://pub.dartlang.org" 129 | source: hosted 130 | version: "0.2.0" 131 | meta: 132 | dependency: transitive 133 | description: 134 | name: meta 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "1.8.0" 138 | path: 139 | dependency: transitive 140 | description: 141 | name: path 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "1.8.2" 145 | plugin_platform_interface: 146 | dependency: transitive 147 | description: 148 | name: plugin_platform_interface 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "2.1.3" 152 | rxdart: 153 | dependency: "direct main" 154 | description: 155 | name: rxdart 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "0.27.7" 159 | sky_engine: 160 | dependency: transitive 161 | description: flutter 162 | source: sdk 163 | version: "0.0.99" 164 | source_span: 165 | dependency: transitive 166 | description: 167 | name: source_span 168 | url: "https://pub.dartlang.org" 169 | source: hosted 170 | version: "1.9.1" 171 | stack_trace: 172 | dependency: transitive 173 | description: 174 | name: stack_trace 175 | url: "https://pub.dartlang.org" 176 | source: hosted 177 | version: "1.10.0" 178 | stream_channel: 179 | dependency: transitive 180 | description: 181 | name: stream_channel 182 | url: "https://pub.dartlang.org" 183 | source: hosted 184 | version: "2.1.0" 185 | string_scanner: 186 | dependency: transitive 187 | description: 188 | name: string_scanner 189 | url: "https://pub.dartlang.org" 190 | source: hosted 191 | version: "1.1.1" 192 | term_glyph: 193 | dependency: transitive 194 | description: 195 | name: term_glyph 196 | url: "https://pub.dartlang.org" 197 | source: hosted 198 | version: "1.2.1" 199 | test_api: 200 | dependency: transitive 201 | description: 202 | name: test_api 203 | url: "https://pub.dartlang.org" 204 | source: hosted 205 | version: "0.4.13" 206 | vector_math: 207 | dependency: transitive 208 | description: 209 | name: vector_math 210 | url: "https://pub.dartlang.org" 211 | source: hosted 212 | version: "2.1.3" 213 | sdks: 214 | dart: ">=2.18.0-146.0.dev <3.0.0" 215 | flutter: ">=1.20.0" 216 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: geoflutterfire2 2 | description: GeoFlutterFire2 is an open-source library that allows you to store and query firestore documents based on their geographic location. 3 | version: 2.3.15 4 | homepage: https://github.com/beerstorm-net/geoflutterfire2 5 | 6 | environment: 7 | sdk: ">=2.12.0 <3.0.0" 8 | flutter: ">=1.17.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | cloud_firestore: ^4.4.4 14 | rxdart: ^0.27.7 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | --------------------------------------------------------------------------------