Last updated:
0 purchases
eliud core
eliud_core #
Build apps with no code. Or with code, of course, if you want.
But then just the code you like to focus on :-)
Introduction
Example Eliud apps
Chapter I. Create a simple "hello world" Android app
Step 1: Decide on domain name and app nickname
Step 2: Create a new google account
Step 3: Create a new firebase project
Step 4: Configure your project
Step 5: Setup Firebase database
Step 6: Setup Firebase storage
Step 7: Setup Google Authentication
Step 8: Generate a Private Key
Step 9: Add Firebase Android App
Step 10: Create Android Studio project
Step 11: Copy google_services.json
Step 12: Apply firebase SDK instructions
Step 13: Add key store file to your project
Step 14: Update pubspec.yaml
Step 15: Update main.dart
Step 16: Clean up
Step 17: minSdkVersion
Step 18: AD_ID
Step 19: Run your app
Step 20: Add some basic functionality to your app
Step 21: Configure your app further
Chapter II. Create the webapp and configure firebase
Step 1: Buy domain
Step 3: Logo
Step 4: Add Firebase Web App
Step 5: Retrieve hosting details
Step 6: Setup email forwarding
Step 7: Subscribe to mailtrap
Step 8: Setup DNS records for firebase hosting
Example 1: domains.google.com
Example 2: squarespace.com
Step 9: Setup DNS records for mailtrap
Example 1: domains.google.com
Example 2: squarespace.com
Step 10: Verify mailtrap setup
Step 11: Update firebase
Step 11.1: Install firebase command line tools
Step 11.2: Enable APIs
Step 11.3: Enable firebase functions
Step 11.4 Update firebase
Step 12: Enable APIs
Step 13: Add Authorized domains to Authentication
Step 14: Configure oauth web client
Step 15: Configure Android Studio project for web
Step 15.1: Update pubspec.yaml
Step 15.2: Update main.dart
Step 15.3: Create images and stylesheet
Step 15.4: Update index.html
Step 16: Cors`
Step 17: Deploy your website
Step 18: Create policies / policy pages
Step 19: Create membership dashboard page
Step 20: Setup oauth consent
Step 21: Start your free google GCP trial 300 USD
Chapter III. Create the ios app
Step 1: Register as apple developer
Step 2: Create or Update an Apple App ID
Step 3: Register your apple device
Step 4: Create an Apple Service ID
Step 5: Register a Private Key for you apple developer account
Step 6: Enable Apple sign-in on Firestore
Step 7: Provide Web Authentication Configuration for your Service ID
Step 8: Create Apple firebase app
Step 9: Setup ios project
Step 10: Configure the Android Studio project for apple
Step 11. GoogleService-Info.plist
Step 12. Info.plist
Step 12.1. Add a URL scheme to your project
Step 12.2. Indicate your app does not use encryption
Step 12.3. Add camera, microphone and photo library access
Step 12.4. Result file
Troubleshouting steps
Chapter IV. Deploy to android store
Step 1. Build
Optional: Step 2. Test the bundle
Step 3. Enroll to Android app store
Step 4. Create App on Google Play
Step 5. Provide App policy details
Step 6. Main store listing
Step 6.1 Create a feature graphic
Step 6.2 Take screenshots
Step 6.2.1 Create virtual machines
Step 6.2.2 Run the app and take screenshots
Step 6.2.3 Create icon 512 x 512 pixels
Step 6.3 Submit main store listing details
Step 7. Store settings
Step 8. Countries/regions
Step 9. Upload for production
Step 10: Sign in
Step 11: Publishing overview
Chapter V. Deploy to apple store
Step 1: Enroll for the Apple Developer Program.
Step 2: Create an app on App Store Connect
Step 3: Provide App Information
Step 4: Create a build archive
Step 5: Upload to App Store Connect
Option 5.1: Use upload tool
Option 5.2: Use transport app
Step 6: Take screenshots
Step 6.1: Create simulators
Step 6.2 Create screenshots
Step 7: Create test user
Step 8: Provide App Privacy details
Step 9: Pricing and Availability
Step 10: Submit the app
Chapter VI. Extend the app with other packages
Chapter VII. Write and integrate your own code / packages
Appendix A. Overview packages
The dependencies of a typical app
Links
Direct dependencies
Introduction #
Documentation for eliud is under construction. Please be patient.
Eliud technology is open source technology.
The technology allows to build apps and/or websites. Today, app content can include photo galleries, pages with videos and images (html), social media, chat with or between members, your shop / shopping cart, photo sliders, documents, and more. A complete list below.
Eliud is a layer on top of Flutter. Flutter is an open-source UI software development kit created by Google. Flutter allows to develop cross platform applications for iOS, Android and web. Flutter supports Linux, macOS, Windows and Google Fuchsia. This hasn't been tested with eliud packages yet.
For those who know Worpress: Eliud is to Flutter as Wordpress is to html:
Html allows you to construct webpages. However, html requires some level of technical knowledge about building webpages.
Wordpress and many other similar technologies allow people without knowledge of html to build webpages and websites.
Flutter allows to build websites and apps, or even Windows, Linux, macOS and Google Fuchsia apps. However, Flutter requires programming skills and technical knowledge.
Eliud allows people without programming skills and technical knowledge to build cross platform apps and websites.
Eliud is pluggable technology, allowing developers
to extend / add functionalities by means of plugins / packages.
to change look and feel through using styles.
A website / app built with Eliud consist of its core Eliud package + one or more Eliud plugins. The app is constructed by configuring it. Configuration, images and videos are stored in Firebase database and Firebase storage.
The below steps document the creation of your own android + apple + web app and includes all instructions, all the way to pushing your app into the apple app store, android store and web.
Example Eliud apps #
These are some example apps which demonstrate what eliud can give you. Everything used is open source, part of eliud project.
App
Ios
Android
Web
Juuwle - An online store for jewels
Juuwle on the App Store
Juuwle on Google Play
https://juuwle.net
Minkey - Community making apps online
This type of app - allowing to create apps from within the app - is not allowed on apple store
Minkey on Google Play
https://minkey.io
Thoma5 - Profile of Thomas. Under construction
Thoma5 on App Store
Thoma5 on Google Play
https://thoma5.com
Chapter I. Create a simple "hello world" Android app #
This guide are all steps to create a minimum android, iOS or web app with Eliud.
Whenever this pops up, make note of this for what this is in your case, as you'll need it at some later stage. In the below text we provided this information whilst creating thoma5, as an example. Obviously for sensitive information, like passwords, we've provided fake info.
Step 1: Decide on domain name and app nickname #
Decide your app name and web domain.
your domain: thoma5.com
your app nickname: Thoma5
Step 2: Create a new google account #
Goto https://www.google.com/account/about/
Select "Create an account"
Follow on screen instructions
(recommended to use default settings)
google account: [email protected]
google account password
Step 3: Create a new firebase project #
Goto https://console.firebase.google.com
Select "Create a project"
And follow on screen instructions
(recommended to use default settings)
firebase project: thoma5
Step 4: Configure your project #
Goto https://console.firebase.google.com
Select your project
Select Project Overview > Project settings
Select support email. Use your google account
Step 5: Setup Firebase database #
Goto https://console.firebase.google.com
Select your project
Select Build > Firebase database
Select "Create database"
And follow on screen instructions (recommended to use default settings, start in production mode)
With Cloud Firestore open, click on Rules and copy/paste the
contents of firestore.rules
and publish.
For convenience, and to familiarise yourself with firebase, at this point we copy/paste these rules.
However, later we will upload the same rules more efficiently using firestore commands from command line
Step 6: Setup Firebase storage #
Goto https://console.firebase.google.com
Select your project
Select Build > Storage
Select "Get started"
And follow on screen instructions (recommended to use default settings, start in production mode)
With Storage open, click on Rules and copy/paste the contents of
storage.rules
and publish.
For convenience, and to familiarise yourself with firebase, at this point we copy/paste these rules.
However, later we will upload the same rules more efficiently using firestore commands from command line
With storage page open, retrieve your "bucket" from the url. You bucket is the bit in front of ".appspot" in the url. In our case the url is https://console.firebase.google.com/project/thoma5/storage/thoma5.appspot.com/files, hence the bucket is thoma5
storage bucket: thoma5
Step 7: Setup Google Authentication #
Goto https://console.firebase.google.com
Select your project
Select Authentication
Select Sign-in method
Select Google from Sign-in providers
Enable the Google sign-in
Step 8: Generate a Private Key #
Run the following command at command prompt:
keytool -genkey -v -keystore your_keystore_filename -storepass your_keystore_storepass -alias your_keystore_alias -keypass your_keystore_keypass -keyalg RSA -keysize 2048 -validity 36524
copied to clipboard
Then follow onscreen instructions. Then store the key-file in a safe place. You will have to use it multiple times in the future.
Now run:
keytool -list -v -alias your_keystore_alias -keystore your_keystore_filename -storepass your_keystore_storepass -keypass your_keystore_keypass
copied to clipboard
For example:
keytool -genkey -v -keystore %USERPROFILE%\\.android\\thoma5.keystore -storepass abc -alias thoma5key -keypass cde -keyalg RSA -keysize 2048 -validity 36524
keytool -list -v -alias thoma5key -keystore %USERPROFILE%\\.android\\thoma5b.keystore -storepass abc -keypass cde
copied to clipboard
your keystore filename: %USERPROFILE%\\.android\\thoma5.keystore
your keystore storepass: abc
your keystore keypass: cde
your keystore alias: thoma5key
your keystore SHA1: A0:B1:C2:D3:E4:F5:A0:B1:C2:D3:E4:F5:A0:B1:C2:D3:E4:F5:AA:BB
MORE INFO
Authenticating Your Client
Android: Generate Release/Debug Keystores (Example)
Step 9: Add Firebase Android App #
Goto https://console.firebase.google.com
Select your project
Click 'Add app' and select platform 'Android'"
Specify your android package name. This must be the inverse of your domain
Specify your android app nickname. This is your app nickname
Paste the SHA-1 key Your keystore SHA1
Press "Register app"
Then download the file google-services.json
your Android app package name: com.thoma5.thoma5_app
your downloaded google-services.json file: C:\Users\johan\Downloads\google-services.json
Step 10: Create Android Studio project #
Start Android studio
Select File > New > New Flutter Project
Specify
Flutter SDK path and press Next
Specify
Project name: e.g. thoma5_app
Project location: e.g. C:\src\apps\thoma5_app
Description: e.g. Thoma5 app
Project type: Should be "Application"
Organization: e.g. com.thoma5
Android language: Should be Java
iOS language: Should be Swift
Platforms: Should be Android, iOS and Web
❗ IMPORTANT ❗
The android package name specified as Your Android app package name - e.g. com.thoma5.thoma5_app - should be equal to the concatenation of organisation - e.g. com.thoma5 - a dot and the project_name - e.g. thoma5_app
Press finish
Flutter SDK path: c:\dev\flutter
Project name: thoma5_app
Organization: com.thoma5
Root dir: C:\src\apps\thoma5_app
Step 11: Copy google_services.json #
Switch to the Project view in Android Studio to see your project root directory.
Move your downloaded google-services.json file into your module (app-level) root directory, e.g. thoma5_app/android/app
Step 12: Apply firebase SDK instructions #
Goto https://console.firebase.google.com
Select your project
Find your app from "your apps" section, then press "See SDK instructions"
You get to chance to re-download the google_services.json file, skip this by pressing next.
Now apply the suggestions provided. Make sure to select Groovy (build.gradle) and Java.
At the time of writing this document, the changes to make were:
file
location
add
(1) thoma5_app/android/build.gradle
buildscripts > dependencies
classpath 'com.google.gms:google-services:4.3.15'
(2) thoma5_app/android/app/build.gradle
plugins
id 'com.google.gms.google-services'
(3) Finally the below at the bottom of thoma5_app/android/app/build.gradle had to be added
dependencies {
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:32.2.2')
implementation 'com.google.firebase:firebase-analytics'
// Add the dependencies for any other desired Firebase products
// https://firebase.google.com/docs/android/setup#available-libraries
}
copied to clipboard
Step 13: Add key store file to your project #
Create key.properties file in your android directory, e.g thoma5/android/key.properties
Populate it with the below keys and values as below. Find your values specified before (follow the links)
storeFile=Your keystore filename
storePassword=Your keystore storepass
keyPassword=Your keystore keypass
keyAlias=Your keystore alias
e.g.
storePassword=abc
keyPassword=cde
keyAlias=thoma5key
storeFile=c:/Users/thomas/.android/thoma5.keystore
copied to clipboard
Add the following lines to your android apps build.gradle file, e.g. thoma5/android/app/build.gradle
Load the properties
plugins {
...
}
// add this after plugins
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
// the rest of the file
...
copied to clipboard
Use the keystore for signinConfigs
android {
defaultConfig {
...
}
// add this after defaultConfig and before buildTypes
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
...
}
}
copied to clipboard
Make sure your buildTypes is pointing to the releasing signingConfigs for both debug and release builds
buildTypes {
release {
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.release
debuggable true
}
}
copied to clipboard
Step 14: Update pubspec.yaml #
Update you pubspec.yaml file to reflect the below
---
name: thoma5_app
description: Thoma5
homepage: https://thoma5.com
repository: https://github.com/eliudio/thoma5_app
version: 1.0.0
environment:
sdk: '>=3.1.0 <4.0.0'
flutter: '>=3.0.0'
dependencies:
flutter:
sdk: flutter
eliud_core: ^1.0.6+1
eliud_pkg_create: ^1.0.7+1
eliud_stl_mona: ^1.0.1+6
dev_dependencies:
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
copied to clipboard
run pub get
Step 15: Update main.dart #
Replace your main.dart with these contents.
import 'package:eliud_core/eliud.dart';
import 'package:eliud_core_model/style/_default/default_style_family.dart';
import 'package:eliud_core/core_package.dart';
import 'package:eliud_pkg_create/creator_package.dart';
import 'package:eliud_pkg_create/tools/basic_app.dart';
import 'package:eliud_pkg_text/text_package.dart';
import 'package:eliud_stl_mona/mona_stl_package.dart';
import 'package:eliud_pkg_create/creator_decoration.dart';
import 'package:eliud_stl_mona/mona_style_family.dart';
import 'package:flutter/cupertino.dart';
import 'package:firebase_core/firebase_core.dart';
Future<void> main() async {
String APP_ID = "THOMA5_APP";
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
var eliud = Eliud();
try {
eliud.registerPackage(CorePackage.instance()); // must be first as it installs apis!
eliud.registerPackage(TextPackage.instance());
eliud.registerPackage(MonaStlPackage.instance());
eliud.registerPackage(CreatorPackage.instance());
// register decorations, these are only required if you want to be able to change your app through the interface
eliud.registerDecoration(CreatorDecoration());
// register style families
eliud.registerStyleFamily(MonaStyleFamily.instance());
eliud.registerStyleFamily(DefaultStyleFamily.instance());
// finish init
eliud.finalizeInitialisation();
} catch (exception) {
throw Exception("Exception whilst initialising the app");
}
// create the app if it doesn't exist
await BasicApp.checkApp(APP_ID);
// let's go !
eliud.run(APP_ID, false);
}
copied to clipboard
APP_ID: THOMA5_APP
Step 16: Clean up #
Delete the directory test, which contains widget_test.dart
Step 17: minSdkVersion #
Goto your Flutter SDK path, subdirectory packages\flutter_tools\gradle\src\main\groovy and edit the file flutter.groovy and open it
Update the value for minSdkVersion to be 21
class FlutterExtension {
...
/** Sets the minSdkVersion used by default in Flutter app projects. */
static int minSdkVersion = 21
...
}
copied to clipboard
❗ REMARK ❗
We only need to make this change to the minSdkVersion for the SDK 1 time, i.e. do not repeat this step for future projects / apps.
Step 18: AD_ID #
To be able to upload our app to the google play store, we must specify that our app doesn't have adds. Obviously if you choose to change this then this is possible, but not scope of this guide. To keep things simple...
Open your AndroidManifest.xml file from your android directory//app/src/main/AndroidManifest.xml, e.g. C:/src/apps/thoma5_app/android/app/src/main/AndroidManifest.xml
Add xmlns:tools="http://schemas.android.com/tools" at the top, in the manifest node
Add the following to the bottom of the document
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
copied to clipboard
That results in our case in the following contents:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<application
android:label="thoma5_app"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
</manifest>
copied to clipboard
Step 19: Run your app #
Run the app. Because this is the first time your start the app, it will install a basic app.
When the app asks to choose an account to login, select your google account
Ones the basic app is created, it will open
Step 20: Add some basic functionality to your app #
After you've started your app in the previous step, a "Hello world" screen should appear.
Press the pen icon to toggle editing mode on.
Then press the - app button
3.1 In the general section of the app:
3.1.1. change the title of your application
3.1.2. change the home url to your domain url. This is constructed with https:// followed by your domain name
3.2 In the "Welcome email document" section, provide a HTML document to welcome new joiners, like the one below. Use ${NAME} to address the person joining.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Welcome new member</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width" />
<style type="text/css">
@media only screen and (max-width:590px){
.c1{
background-color:white !important;
}
.c3a,
.c3b{
width:100% !important;
}
}
</style>
</head>
<body>
<center>
<table border="0" cellpadding="0" height="100" width="100%">
<tr>
<td align="center" valign="middle">
Welcome to Thoma5. Thanks for joining, ${NAME}.
</td>
</tr>
<tr>
<td align="center" valign="middle">
As a member, enjoy
<ul>
<li>the "feed", where you can share photos, videos, messages, documents.
</li>
<li>the chat, where you can chat with other members.
</li>
</ul>
</td>
</tr>
<tr>
<td align="center" valign="middle">
Enjoy the app ${NAME}!
</td>
</tr>
</table>
</center>
</body>
</html>
copied to clipboard
When in edit mode, press the wizard icon to open the wizard dialog box.
We have only activated a few packages in the code (using eliud.registerPackage), so hence not many wizards are initially available.
Select signinbutton and press Go!
Then select signoutbutton and press Go!
Step 21: Configure your app further #
At some point in the process you will obviously want to add more functionality to your app.
In this document you find more details how to do so
Chapter II. Create the webapp and configure firebase #
In the previous steps we've done the foundation to build an app. The next big step is to introduce
web deployment
authentication
functions to support packages
Step 1: Buy domain #
Buy your domain name, e.g. on squarespace.com.
Step 3: Logo #
create a logoand store into a file in your project directory, e.g. assets/logo/thoma5-logo-1.png
logo: assets/logo/thoma5-logo-1.png
add the below to pubspec.yaml
dev_dependencies:
flutter_launcher_icons: ^0.13.1
flutter_launcher_icons:
android: true
ios: true
image_path: assets/logo/thoma5-logo-1.png
image_path_ios: assets/logo/thoma5-logo-1.png
remove_alpha_ios: true
web:
generate: true
image_path: assets/logo/thoma5-logo-1.png
copied to clipboard
Run the below from your app directory
flutter pub run flutter_launcher_icons:main
copied to clipboard
Step 4: Add Firebase Web App #
Goto https://console.firebase.google.com
Select your project
Click 'Add app' and select platform 'Web'"
Provide your app nickname your app nickname
Select Firebase Hosting.
Select your project from the drop down box.
Click on Register app.
From the "Add Firebase to your web app" page, copy the firebaseConfig details
firebaseConfig
const firebaseConfig = {
apiKey: "ABcdEfG_H1Ij2KLmNo3PQ_RstUvwXY4Zabcdefg",
authDomain: "thoma5.firebaseapp.com",
projectId: "thoma5",
storageBucket: "thoma5.appspot.com",
messagingSenderId: "263405528229",
appId: "1:123456789012:web:1a2345b6c7890d12ef345h",
measurementId: "G-WL1A23456C"
};
copied to clipboard
Step 5: Retrieve hosting details #
Goto https://console.firebase.google.com
Find the "Add custom domain" button and add
thoma5.com
www.thoma5.com, and configure to redirect to thoma5.com
Make note of the DNS records. We'll need this in a later step.
DNS records
Domain: thoma5.com
Record type
Host
Value
A
thoma5.com
123.123.123.123
TXT
thoma5.com
hosting-site=thoma5
TXT
_acme-challenge.thoma5.com
aBcdE1FghIj23k4lmnoPqrstUvw5xyZabcdeF6GHiJk
Domain: www.thoma5.com
Record type
Host
Value
CNAME
www.thoma5.com
thoma5.web.app
Step 6: Setup email forwarding #
Setup email forwarding
from [email protected]
to: your google account
official email: [email protected]
Step 7: Subscribe to mailtrap #
https://mailtrap.io/
Select sign up
Select "Use google account" and select your google account
Select "Email Sending", enter your domain and press "Add Your DomaiN"
Make note of the DNS records. We'll need this in a later step.
DNS records
Status
Category
Type
Name
Value
Missing
Domain Verification
CNAME
1abcdef2g34hijkl
smpt.mailtrap.live
Missing
SPF
TXT
-
v=spf1 include:_spf.smtp.mailtrap.live ~all
Missing
DKIM
CNAME
rwmt1._domainkey
rwmt1.dkim.smtp.mailtrap.live
Missing
DKIM
CNAME
rwmt2._domainkey
rwmt2.dkim.smtp.mailtrap.live
Missing
DMARC
TXT
_dmarc
v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; rf=afrf; pct=100
Missing
Custom domain tracking
CNAME
mt-link
t.mailtrap.live
Click next and in the SMTP/API Settings click API
Press the "Copy" next to Api Token and keep it somewhere safe. We'll need it soon.
mailtrap token: a1bc234d5e6f7890123ghij45678k901
Step 8: Setup DNS records for firebase hosting #
Follow the guidelines of your domain registrar to configure your DNS in line with the
DNS records specified in the firebase hosting dashboard.
Example 1: domains.google.com #
Login into your account on https://domains.google.com
Select "DNS"
Select "Manage custom records"
Create new records with the below information, obviously adjusted in line with your DNS records
Host name
Type
TTL
Data
_acme-challenge
TXT
N/A
aBcdE1FghIj23k4lmnoPqrstUvw5xyZabcdeF6GHiJk
A
N/A
123.123.123.123
TXT
N/A
hosting-site=thoma5
www
CNAME
N/A
thoma5.web.app
Example 2: squarespace.com #
For squarespace, for thoma5.com, this would the be done following these steps:
Login into your account on https://www.squarespace.com/
Select your domain from your domains and select "Manage domain settings"
Edit DNS
Add the below records, obviously adjusted in line with your DNS records
Host
Type
Priority
Data
_acme-challenge
TXT
N/A
aBcdE1FghIj23k4lmnoPqrstUvw5xyZabcdeF6GHiJk
@
A
N/A
123.123.123.123
@
TXT
N/A
hosting-site=thoma5
www
CNAME
N/A
thoma5.web.app
MORE INFO
Connect a custom domain
Step 9: Setup DNS records for mailtrap #
Follow the guidelines of your domain registrar to configure your DNS in line with the
DNS records specified in the mailtrap dashboard.
Example 1: domains.google.com #
Login into your account on https://domains.google.com
Select "DNS"
Select "Manage custom records"
Create new records with the below information, obviously adjusted with your DNS records
Host name/td>
Type
TTL
Data
1abcdef2g34hijkl
CNAME
3600
smtp.mailtrap.live
TXT
3600
v=spf1 include:_spf.smtp.mailtrap.live ~all
rwmt1._domainkey
CNAME
3600
rwmt1.dkim.smtp.mailtrap.live
rwmt2._domainkey
CNAME
3600
rwmt2.dkim.smtp.mailtrap.live
_dmarc
TXT
3600
v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; rf=afrf; pct=100
mt-link
CNAME
3600
t.mailtrap.live
Example 2: squarespace.com #
For squarespace, for thoma5.com, this would the be done following these steps:
Login into your account on https://www.squarespace.com/
Select your domain from your domains and select "Manage domain settings"
Edit DNS
Add the below records, obviously adjusted in line with your DNS records
Host
Type
Priority
Data
1abcdef2g34hijkl
CNAME
3600
smtp.mailtrap.live
@
TXT
3600
v=spf1 include:_spf.smtp.mailtrap.live ~all
rwmt1._domainkey
CNAME
3600
rwmt1.dkim.smtp.mailtrap.live
rwmt2._domainkey
CNAME
3600
rwmt2.dkim.smtp.mailtrap.live
_dmarc
TXT
3600
v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]; rf=afrf; pct=100
mt-link
CNAME
3600
t.mailtrap.live
MORE INFO
Sending Domain Setup - Mailtrap Knowledge Base
Step 10: Verify mailtrap setup #
Goto mailtrap.io and sign in with your google account
From your dashboard, select Email Sending, then Sending Domains
In the domain verification, select Verify all to verify if you've setup your DNS records correctly
Follow the steps in Verify Setup, i.e. you'll have to answer some security questions to prove you're building a legit app. In our experience this has been a straightforward process. Questions:
Describe business / project
Website
Linked in profile
What type of emails do you plan to send?
How do you get the list of recipients?
Amount of emails planning to send / month
Step 11: Update firebase #
In this step we wil be updating / uploading:
storage rules
firestore indexes and rules
functions
We have uploaded rules in previous steps during the quick start.
That was to get up and running quickly. The proper way to update
rules is by using the firebase command line tools, which we will do in
this step.
Step 11.1: Install firebase command line tools #
Open cmd
Run npm install -g firebase-tools
Step 11.2: Enable APIs #
Goto https://cloud.google.com/build/docs/deploying-builds/deploy-firebase
Click "Enable the APIs"
Follow on screen instructions
Step 11.3: Enable firebase functions #
Goto https://console.firebase.google.com
Select your project
Select functions
Press "Get started" and select next
Step 11.4 Update firebase #
Run the below (change firebase project and storage bucket to yours)
mkdir c:\src\apps\thoma5_app_firebase
cd c:\src\apps\thoma5_app_firebase
git clone https://github.com/eliudio/firebase.git
cd c:\src\apps\thoma5_app_firebase\firebase
firebase logout
firebase login
firebase functions:config:set mailtrap.token=a1bc234d5e6f7890123ghij45678k901 [email protected] mailtrap.sender.name=Thoma5 app.appname="Thoma5" app.collectionname="order" app.bucket="thoma5" stripe.secret=lalalala --project "thoma5"
firebase deploy --project thoma5
copied to clipboard
Where...
mailtrap.tokenmailtrap token
[email protected]
mailtrap.sender.nameThoma5
app.collectionnameorder
app.bucketstorage bucket
projectfirebase project
❗ NOTES ❗
You can use quotes to specify parameters. E.g. You could use sendgrid.apikey="NO KEY"
In the rules, indexes and functions we cover ALL packages that currently exist.
If you only use some packages, then these obsolete rules, indexes and functions could
be considered obsolete. However, they're harmless being there and it's the easiest
way to get going.
When you require your own functions, we recommend to organise multiple functions as described here: https://firebase.google.com/docs/functions/organize-functions?gen=2nd
Step 12: Enable APIs #
Enable People API: https://console.developers.google.com/apis/api/people.googleapis.com
Step 13: Add Authorized domains to Authentication #
The following is required to login with oauth, e.g. when signing in with Apple from your webapp.
Goto https://console.firebase.google.com
Select your project
Select Authenticaiton > Settings
In Authorized domains tab, add domain your domain name, here thoma5.com
Step 14: Configure oauth web client #
Goto https://console.cloud.google.com/apis/credentials
Find the OAuth 2.0 Client IDs with name "Web client". If you find more than one, select any, e.g. the first.
Find the "ADD URI" and add these domains:
https://thoma5.com
https://www.thoma5.com
https://thoma5.web.app
Find "web client" and copy the client ID
Press SAVE
Web client ID: x-y.apps.googleusercontent.com
Step 15: Configure Android Studio project for web #
Step 15.1: Update pubspec.yaml #
Add the below dependency to pubspec.yaml
eliud_pkg_wizards: ^1.0.4
copied to clipboard
This will result in your pubspec.yaml file to look like:
---
name: thoma5_app
description: Thoma5
homepage: https://thoma5.com
repository: https://github.com/eliudio/thoma5_app
version: 1.0.0
environment:
sdk: '>=3.1.0 <4.0.0'
flutter: '>=3.0.0'
dependencies:
flutter:
sdk: flutter
eliud_core: ^1.0.7
eliud_pkg_create: ^1.0.7+1
eliud_pkg_wizards: ^1.0.4
eliud_stl_mona: ^1.0.1+6
dev_dependencies:
flutter_lints: ^2.0.0
flutter_launcher_icons: ^0.13.1
flutter:
uses-material-design: true
flutter_icons:
android: launcher_icon
ios: false
image_path: assets/logo/thoma5-logo-1.png
copied to clipboard
Run pub get
Step 15.2: Update main.dart #
Add the following imports to main.dart
import 'package:flutter/foundation.dart';
import 'package:eliud_pkg_wizards/wizards_package.dart';
import 'package:eliud_pkg_etc/etc_package.dart';
import 'package:eliud_pkg_medium/medium_package.dart';
import 'package:eliud_pkg_workflow/workflow_package.dart';
copied to clipboard
Replace the Firebase.initializeApp() line in your main.dart with the below:
Make sure the values for apiKey -> measurementId correspond with your values available from firebaseConfig
if (kIsWeb) {
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: "ABcdEfG_H1Ij2KLmNo3PQ_RstUvwXY4Zabcdefg",
authDomain: "thoma5.firebaseapp.com",
projectId: "thoma5",
storageBucket: "thoma5.appspot.com",
messagingSenderId: "263405528229",
appId: "1:123456789012:web:1a2345b6c7890d12ef345h",
measurementId: "G-WL1A23456C"
));
} else {
await Firebase.initializeApp();
}
copied to clipboard
Add the following extra eliud-dependencies:
eliud.registerPackage(WizardsPackage.instance());
copied to clipboard
So basically your main.dart will look like
import 'package:eliud_core/eliud.dart';
import 'package:eliud_core_model/style/_default/default_style_family.dart';
import 'package:eliud_core/core_package.dart';
import 'package:eliud_pkg_create/creator_package.dart';
import 'package:eliud_pkg_create/tools/basic_app.dart';
import 'package:eliud_pkg_text/text_package.dart';
import 'package:eliud_stl_mona/mona_stl_package.dart';
import 'package:eliud_pkg_create/creator_decoration.dart';
import 'package:eliud_stl_mona/mona_style_family.dart';
import 'package:flutter/cupertino.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:eliud_pkg_wizards/wizards_package.dart';
import 'package:eliud_pkg_etc/etc_package.dart';
import 'package:eliud_pkg_medium/medium_package.dart';
import 'package:eliud_pkg_workflow/workflow_package.dart';
Future<void> main() async {
String APP_ID = "THOMA5_APP";
WidgetsFlutterBinding.ensureInitialized();
if (kIsWeb) {
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: "ABcdEfG_H1Ij2KLmNo3PQ_RstUvwXY4Zabcdefg",
authDomain: "thoma5.firebaseapp.com",
projectId: "thoma5",
storageBucket: "thoma5.appspot.com",
messagingSenderId: "263405528229",
appId: "1:123456789012:web:1a2345b6c7890d12ef345h",
measurementId: "G-WL1A23456C"
));
} else {
await Firebase.initializeApp();
}
var eliud = Eliud();
try {
eliud.registerPackage(CorePackage.instance()); // must be first as it installs apis!
eliud.registerPackage(TextPackage.instance());
eliud.registerPackage(MonaStlPackage.instance());
eliud.registerPackage(CreatorPackage.instance());
eliud.registerPackage(WizardsPackage.instance());
// register decorations, these are only required if you want to be able to change your app through the interface
eliud.registerDecoration(CreatorDecoration());
// register style families
eliud.registerStyleFamily(MonaStyleFamily.instance());
eliud.registerStyleFamily(DefaultStyleFamily.instance());
// finish init
eliud.finalizeInitialisation();
} catch (exception) {
throw Exception("Exception whilst initialising the app");
}
// create the app if it doesn't exist
await BasicApp.checkApp(APP_ID);
// let's go !
eliud.run(APP_ID, false);
}
copied to clipboard
Step 15.3: Create images and stylesheet #
Optional: Verify the favicon.png that has been generated before, and optionally create your own (in the web folder). Size is 16 x 16. Use logo as input.
Download loading.gif
Download loading.gif and copy into the icons directory of your web folder
Download styles.css
Download styles.css and copy into the root directory of your web folder
Step 15.4: Update index.html #
Add the stylesheet
<link rel="stylesheet" type="text/css" href="styles.css">
copied to clipboard
Add the Web client ID in metadata
<!== Google sign-in -->
<meta name="google-signin-client_id" content="x-y.apps.googleusercontent.com">
copied to clipboard
Add the loading gif
<div id="progress">
</div>
<script>
var img = document.createElement("img");
img.className = "center";
img.src = "icons/loading.gif";
var src = document.getElementById("progress");
src.appendChild(img);
</script>
copied to clipboard
Initialise pdfjs
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.js" type="text/javascript"></script>
<script type="text/javascript">
pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.worker.min.js";
pdfRenderOptions = {
cMapUrl: 'https://cdn.jsdelivr.net/npm/[email protected]/cmaps/',
cMapPacked: true,
}
</script>
copied to clipboard
Review meta data description and name
Which results in the below index.html for thoma5
<!DOCTYPE html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF">
<link rel="stylesheet" type="text/css" href="styles.css">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="Thoma5">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Thoma5">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!== Google sign-in -->
<meta name="google-signin-client_id" content="x-y.apps.googleusercontent.com">
<!-- Favicon -->
<link rel="icon" type="image/png" href="icons/favicon.png"/>
<title>Thoma5</title>
<link rel="manifest" href="manifest.json">
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = null;
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
<div id="progress">
</div>
<script>
var img = document.createElement("img");
img.className = "center";
img.src = "icons/loading.gif";
var src = document.getElementById("progress");
src.appendChild(img);
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.js" type="text/javascript"></script>
<script type="text/javascript">
pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.worker.min.js";
pdfRenderOptions = {
cMapUrl: 'https://cdn.jsdelivr.net/npm/[email protected]/cmaps/',
cMapPacked: true,
}
</script>
<div id="loading"></div>
<script>
window.addEventListener('load', function(ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: function(engineInitializer) {
engineInitializer.initializeEngine().then(function(appRunner) {
appRunner.runApp();
});
}
});
});
</script>
</body>
</html>
copied to clipboard
Step 16: Cors` #
To allow images to be accessed / copied, we need to configure cors access.
goto your app root dir
create the following file cors.json
[
{
"origin": ["*"],
"method": ["GET"],
"maxAgeSeconds": 3600
}
]
copied to clipboard
run this command and login with your
gcloud config set project thoma5
gcloud auth login
copied to clipboard
run this gsutil command, make sure to replace "thoma5.appspot.com" with your
storageBucket which you can find from your firebaseConfig
gsutil cors set cors.json gs://thoma5.appspot.com
copied to clipboard
MORE INFO
Stackoverflow
Step 17: Deploy your website #
Create file firebase.json in your app root directory with these contents
{
"hosting": {
"public": "build/web",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
copied to clipboard
From your app root dir, build and deploy your website
flutter build web --release --no-tree-shake-icons
rem flutter build web --web-renderer html --release --no-tree-shake-icons
call firebase login
call firebase deploy --project thoma5
copied to clipboard
COMMENT
When you make code changes, e.g. add package dependencies then you will need to repeat 2. to make your changes available on the web. In other words: no other steps - e.g. CORS - need to be repeated.
We use no-tree-shake-icons during our builds. The icons we use in our app are configured / configurable and hence we can not use tree-shake-icons. More details here.
Step 18: Create policies / policy pages #
When publishing apps to the Google Play or Apple App Store, you will need to
provide links to privacy policy, terms of service and/or disclaimer.
We recommend providing all 3.
For more information, see policies.pdf
To create policies, at this stage, you can choose to use your website or your android app.
We're using the web app as we find the interface easier for the below actions.
Also, when using the web app we can actually get the URL of the policies easier than with the app.
For each policy, follow these steps:
Create a pdf of your policy, then export a jpg for each page and store these files into assets/legal/policy-x-page-b.jpg, ...
Open your app. We open thoma5.com
Login with your google account
Run the policy wizard to create a new policy and accept all default values.
Open your left drawer and select "drawer1" button
In "Current menu items" find the page you've created in 4 and open details
In "General" change the Text and Description, e.g. "Privacy Policy" and confirm the change
From the left drawer, open the policy
Press the button "page" which you can find at the left center of your page and select "Update page"
In general change the Description and Title of the page, e.g. "Privacy Policy"
Press the button "policyPresentation" which you can find at the left top of your page
Click the AppPolicy and then select the Update button
Press the Pages button
Delete the existing page and add all the you've saved as jpg files in 1.
Construct the url:
From your web app: open left drawer, select your policy and copy the URL from your browser address bar
From android app: update the policy page, copy the key from the general section. Now construct the URL:
Start with https://
Add your domain name and a slash: thoma5.com/
Add your APP_ID and a slash: #THOMA5_APP/
Add the policy page key: 8a75d3fa-d8e9-4ac8-9eb7-851010807502-policy
Now repeat for all 3 policies and record the url's
Privacy policy URL: https://thoma5.com/#THOMA5_APP/8a75d3fa-d8e9-4ac8-9eb7-851010807502-policy
Terms of Service URL: https://thoma5.com/#THOMA5_APP/9af69563-a90b-47e1-98e1-bbae6d35a041-policy
Disclaimer URL: https://thoma5.com/#THOMA5_APP/c1470606-b42a-491d-9aa0-c1189189ee78-policy
Step 19: Create membership dashboard page #
A membership dashboard page allows members to request the data that your website / app stores of that person and allows to deactivate the account and destroy all data that we keep of this person.
There are many reasons to have a membership dashboard page.
One is because we want to provide our users the best experience possible. And if they like to leave our site, without leaving a trace, then that's what we offer.
Second is to be in line with regulations.
Third is because when uploading the app to android play store, we must provide a link to a page to allow actions
Run the memberdashboard wizard (from the usual wizard dialog)
Open the memberdashboard. A dialog (!) for the memberdashboard opens. This means that we don't have a page, but have a dialog.
Find your dialog ID.
From your web app: copy the URL from your browser address bar and find the dialog ID after the last occurance of /
From android app:
Press the dialog button
Find the key from General section
Here ecd648b7-68a6-4ebb-94b1-d2211c2f7b8f-member_dashboard
Run the welcome wizard and create a (blank) page. This page should not be accessible from any menu, i.e. deselect AppBar, Home menu and left and right drawer, but select "Available". The page should open after having been created. However, if for some reason you need to find and open it yourself: open "App" from editor mode, select Pages and find the "Welcome" page. Click the menu next to the page and select "Show page".
Update the page so that it's title is "Membership dashboard" and have empty html contents.
Copy the key of the page, here 2ffb7c1e-0a84-4f73-bac9-31c57ffb12c4-page
Now construct the membership URL:
Start with https://
Add domain name and a slash: thoma5.com/
Add your APP_ID and a slash: #THOMA5_APP/
Add the membership dashboard page retrieved in step 6, i.e. here 2ffb7c1e-0a84-4f73-bac9-31c57ffb12c4-page
Add a /
Add the membership dialog ID, retrieved in step 3, i.e. here ecd648b7-68a6-4ebb-94b1-d2211c2f7b8f-member_dashboard
Member dashboard URL: https://thoma5.com/#THOMA5_APP/2ffb7c1e-0a84-4f73-bac9-31c57ffb12c4-page?open-dialog=ecd648b7-68a6-4ebb-94b1-d2211c2f7b8f-member_dashboard
You should test this URL. Try testing it from a new browser, after having logged out from your site. A dialog will appear to allow to login, after which that membership dashboard will open.
Step 20: Setup oauth consent #
TODO
https://console.cloud.google.com/apis/credentials/consent
select user type "External"
select "create"
fill in the details requested:
provide a logo
privacy policy will be available from https://[your domain name[/#[app name in code]/privacy_policy-1. In our example:
https://juuwle.net/#JUUWLE_APP/privacy_policy-1
We will make the terms of service available from https://[your domain name[/#[app name in code]/terms_of_service-1. In our example:
https://juuwle.net/#JUUWLE_APP/terms_of_service-1
Add your domain as Authorised domains, here juuwle.net
Specify developers email address
Add scopes:
.../auth/userinfo.email
.../auth/userinfo.profil
Then press the "In production" button and go through the on screen instructions
NOTES:
Your app will be available to any user with a Google Account.
You've configured your app in a way that requires verification . To complete verification, you will need to provide:
An official link to your app's Privacy Policy, use #privacy_policy_url
A YouTube video showing how you plan to use the Google user data you get from scopes
A written explanation telling Google why you need access to sensitive and/or restricted user data
All your domains verified in Google Search Console
3.6 You will receive an email "OAuth Verification Request for Project"
Follow instructions in the email
Step 21: Start your free google GCP trial 300 USD #
TODO: https://cloud.google.com/free
Chapter III. Create the ios app #
a brief overview of the current base packages
Step 1: Register as apple developer #
Goto https://developer.apple.com/programs/enroll/
Follow the on-screen instructions
Team ID: 123AB4CDEF
Developer account email: [email protected]
Developer account password: password
Step 2: Create or Update an Apple App ID #
https://developer.apple.com/account/resources/identifiers/list
Press '+' next to "Identifiers"
Select "App IDs" and press continue
Select APP and continue
Description: your app nickname
Explicit bundle ID: Explicit
Provide the bundle ID. This is constructed by the invers of your domain name" + your app nickname suffixed with 'ios', here com.thoma5.thoma5ios. Do not use '_'
Enable "Sign in with Apple". No need to press "Edit"
Press "continue"
Press "register"
App Bunble ID: com.thoma5.thoma5ios
App ID Prefix: 123AB4CDEF
Step 3: Register your apple device #
To be able to develop on your ipad / iphone, you need to register your device. Run these steps:
https://developer.apple.com/account/resources/devices/list
Press '+' next to "Devices"
Select your device name, e.g. iOS, iPadOS, ...
Provide a device name, e.g. "My dev ipad"
Specifiy the UDID of your device
MORE INFO
To find the UDID of our devices, this can help...
To find the UDID on macbook: Click apple icon > About This Mac > More Info.. > System Report > Hardware > Hardware Overview and find the UDID next to "Provisioning UDID".
For other devices we've found How to Find Your iPhone or iPad's UDID useful.
Step 4: Create an Apple Service ID #
https://developer.apple.com/account/resources/identifiers/list/serviceId
Press '+' next to "Identifiers"
Select "Services IDs" and press continue
Description: your app nickname, here Thoma5
Identifier: This is constructed by the invers of your domain name" + your app nickname suffixed with 'service', here com.thoma5.thoma5service
Press save
Press register
Service Description: Thoma5
Service identifier: com.thoma5.thoma5service
Step 5: Register a Private Key for you apple developer account #
https://developer.apple.com/account/resources/authkeys/list
Press '+' next to "Keys"
Provide key name, here Thoma5
Enable "Sign in with Apple"
Press "Configure" next to "Sign in with Apple"
Select your App ID from the list which corresponds to the App Bunble ID and App ID Prefix
Press "Save"
Press "Continue"
Press Register
Save key ID and download the key
Key ID: 12ZYXWVUTS
Private keyC:\Users\thomas\Downloads\AuthKey_12ZYXWVUTS.p8
Press "Done"
Step 6: Enable Apple sign-in on Firestore #
Goto https://console.firebase.google.com
Select your project
Select "Authentication"
Select "Sign-in method"
Press "Add new provider"
Select "Apple"
Enable it with the switch "Enable"
Services ID, specify value of Service ID, here com.thoma5.thoma5service
Apple team ID, find "Team ID" from https://developer.apple.com/account/
Expand OAuth code flow configuration
Apple team ID, specify value of Team ID, here 123AB4CDEF
Key ID, specify value of Key ID, here 12ZYXWVUTS
Private key, specify contents of Private key
Finally copy the authorisation callback URL to be used in the next step
Authorisation callback URL: https://thoma5.firebaseapp.com/__/auth/handler
Step 7: Provide Web Authentication Configuration for your Service ID #
https://developer.apple.com/account/resources/identifiers/list/serviceId
Find the service with IDENTIFER = Service identifier
Enable "Sign in with Apple"
Click Configure next to "Sign in with Apple"
Primary App ID: select the app with app that corresponds with the App Bunble ID and App ID Prefix, here 123AB4CDEF.com.thoma5.thoma5ios
Domains and Subdomains: specify domain name, here thoma5.com
Return URLs: specify the Authorisation callback URL, here https://thoma5.firebaseapp.com/__/auth/handler
Press "Next"
Press "Done"
Press "Continue"
And finally press "Save"
Step 8: Create Apple firebase app #
Goto https://console.firebase.google.com
Select your project
Press "Add app"
Select "iOS"
Apple bundle ID: App Bunble ID, here com.thoma5.thoma5ios
App nickname: your app nickname, here Thoma5
App Store ID (optional): leave blank
Press "Register app"
Press "Download GoogleService-info.plist"
Key ID: 12ZYXWVUTS
GoogleService-info.plistC:\Users\thomas\Downloads\GoogleService-info.plist
Press "Next", 3 times
Press "Continue to the console"
Step 9: Setup ios project #
Clone your code on your apple machine
Open the Android Studio project
Step 10: Configure the Android Studio project for apple #
From Android Studio, right click your project root directory/ios/Runner.xcworkspace and select Flutter > Open iOS module in Xcode
In Xcode, select Runner folder, then from the list of TARGETS, select Runner
Then click the "Signing & Capabilities" tab
From the team field, select your team
For bundle identifier, specify your App Bunble ID, here com.thoma5.thoma5ios
Press "+ Capability" then double click "Sign in with Apple"
Don't forget to select Team
Step 11. GoogleService-Info.plist #
Copy GoogleService-info.plist from your windows machine to your macbooks, in our case c:\Users\thomas\Downloads\GoogleService-info.plist
From Xcode, from project Runner, right click folder Runner and select 'Add Files to "Runner"'
Select the file GoogleService-info.plist you've copied to your macbook
Makes sure “copy items if needed" is checked
Press "Add"
After adding file, find the entry "REVERSED_CLIENT_ID" and copy it's value
REVERSED_CLIENT_ID: com.googleusercontent.apps.YOUR REVERSED_CLIENT_ID
Step 12. Info.plist #
Open ios/Runner/Info.plist with a text editor and ...
Step 12.1. Add a URL scheme to your project #
Add the below entry, make sure to use your REVERSED_CLIENT_ID
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>[com.googleusercontent.apps.YOUR REVERSED_CLIENT_ID]</string>
</array>
</dict>
</array>
copied to clipboard
MORE INFO
Get Started With Google Sign-in for iOS and macOD
Step 12.2. Indicate your app does not use encryption #
This is a requirement for app subscription.
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
copied to clipboard
MORE INFO
ITSAppUsesNonExemptEncryption
Step 12.3. Add camera, microphone and photo library access #
Add the below entrie
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library in case you like to add photos to reviews of products.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires access to the microphone in case you like to add comments to reviews of products.</string>
<key>NSCameraUsageDescription</key>
<string>This app requires access to the camera in case you like to add videos to reviews of products..</string>
copied to clipboard
Step 12.4. Result file #
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Juuwle</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>juuwleios</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.x-y</string>
</array>
</dict>
</array>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library in case you like to add photos to reviews of products.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires access to the microphone in case you like to add comments to reviews of products.</string>
<key>NSCameraUsageDescription</key>
<string>This app requires access to the camera in case you like to add videos to reviews of products..</string>
</dict>
</plist>
copied to clipboard
Troubleshouting steps #
In case you encounter errors whilst running the app, the errors you come across might be one of the following.
Issue: Failure of running the app due to processor incompatibility issues.
Solution: Goto the ios directory and run:
sudo arch -x86_64 gem install ffi
arch -x86_64 pod install
copied to clipboard
Error "The operation couldn’t be completed. Unable to launch com.example.x.y.z-icloud.com because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.�
Solution: On your iPhone/tablet open Settings > General > Device Management > Apple Development: [email protected] then select trust at the top.
iOS crash with a stack trace and a message "the default Firebase app has not yet been configured. Add [FIRApp configure]; (FirebaseApp.configure() in Swift) to your application"
Solution: https://medium.com/vector-com-mm/how-to-fix-ios-crash-during-the-start-firebase-configure-f3477df3154
Chapter IV. Deploy to android store #
Below the minimum required (unless indicated) steps to make your app available on android store. As you will see, the app google provides to upload, maintain, test apps is much broader than what we discuss. We do the bare minimum.
Step 1. Build #
From your app root directory, run:
flutter clean
flutter build appbundle --release --no-tree-shake-icons -t lib/main.dart
copied to clipboard
Record the output file
Android bundle: build\app\outputs\bundle\release\app-release.aab
Optional: Step 2. Test the bundle #
Download bundletool from https://github.com/google/bundletool/releases/ and save in c:\dev\bundletool
From your app root directory, generate a set of APKs from your app bundle using the bundletool. Make sure to provide the following:
--bundle: Android bundle
--output:
--ks: your keystore filename
--ks-key-alias: your keystore alias
java -jar c:\dev\bundletool\bundletool-all-1.5.0.jar build-apks ^
--bundle=build/app/outputs/bundle/release/app-release.aab ^
--output=build/app/outputs/bundle/release/thoma5.apks ^
--ks=%USERPROFILE%\\.android\\thoma5.keystore ^
--ks-key-alias=thoma5key
copied to clipboard
When asked provide your your keystore storepass
If you've previously installed your app during development on your android device, then remove it.
Install the app
set ANDROID_HOME=C:\Users\johan\AppData\Local\Android\Sdk
java -jar c:\dev\bundletool\bundletool-all-1.5.0.jar install-apks --apks=build/app/outputs/bundle/release/thoma5.apks
copied to clipboard
Step 3. Enroll to Android app store #
https://play.google.com/console/signup and follow on-screen instructions
Step 4. Create App on Google Play #
https://play.google.com/console
Push "Create App" button
Provide app details and press Create app
Step 5. Provide App policy details #
https://play.google.com/console
Select your app
Select "Policy and programmes" > "App content" and then provide details for all declarations that need attention. You will need:
Privacy policy URL, here https://thoma5.com/#THOMA5_APP/8a75d3fa-d8e9-4ac8-9eb7-851010807502-policy and press "Save"
Member dashboard URL: her ehttps://thoma5.com/#THOMA5_APP/2ffb7c1e-0a84-4f73-bac9-31c57ffb12c4-page?open-dialog=ecd648b7-68a6-4ebb-94b1-d2211c2f7b8f-member_dashboard
Step 6. Main store listing #
Step 6.1 Create a feature graphic #
Create a feature graphic PNG or JPG format 1014 x 500
Feature graphic: C:\src\apps\thoma5_app\assets\other\thoma5-feature-graph.png
Step 6.2 Take screenshots #
Step 6.2.1 Create virtual machines #
Start Android Studio
Select "Tools" > Device Manager
Select "Create device"
Press "New Hardware Profile" and create the first hardware profile as listed in the table below
Press "Next" and select an system image with API level 29
Allow all default settings and press "Finish"
Name
Device type
Screen size
Resolution
RAM
Has Hardware Buttons
Has Harware Keyboard
Navigation Style
Phone 16:9
Phone/Tablet
5.96"
1440 x 2560
2048 MB
/
/
/
Tablet 7" inch 16:9
Phone/Tablet
7"
1024 x 576
2048 MB
/
/
/
Tablet 10" inch 16:9
Phone/Tablet
10"
3200 x 1800
2048 MB
/
/
/
Step 6.2.2 Run the app and take screenshots #
From Android Studio, run your app on the abvove virtual machines
Take take 2-8 screenshots from the phone and 1-8 screenshots from each of the 2 tablets
Record the filenames
Android screenshots: C:\src\apps\thoma5_app\assets\screenshots\*.jpg
Step 6.2.3 Create icon 512 x 512 pixels #
Provide a <a href="logo>logo png file with resolution 512 x 512
Logo: C:\src\apps\thoma5_app\assets\logo\thoma5-512.png
Step 6.3 Submit main store listing details #
https://play.google.com/console
Select your app
Select "Grow" > "Main store listing"
Provide your app name, i.e. your app nickname
Provide a short and full description
Provide your app icon, i.e. Logo
Provide your feature graphic, i.e. Feature graphic
Provide screenshots for phone, 7-inch and 10-inch tablet, i.e. Android screenshots
Step 7. Store settings #
https://play.google.com/console
Select your app
Select "Grow" > "Store settings"
Press "Edit" in "App category", provide App and select a category, here "Education"
Press "Save", then close
Press "Edit" in "Store listing contact details" and provide your
a. Email address: google account, here [email protected]
b. Optionally your phone number
c. Optionally your website, e.g. your domain prefixed with https://, here https://thoma5.com
Press "Save", then close
Step 8. Countries/regions #
https://play.google.com/console
Select your app
Select "Release" > "Production"
Select "Countries/regions"
Select "Add countries/regions"
Check All countries
Press "Save"
Step 9. Upload for production #
https://play.google.com/console
Select your app
Select "Release" > "Production"
Press "Create new release"
Press "Choose signing key", then select "Use Google-generated key"
Press "Upload" from "App bundles" then select your Android bundle, here build\app\outputs\bundle\release\app-release.aab
Provide a release name, e.g. "1 (1.0.0)"
Provide release notes, e.g.
<en-GB>
First release
</en-GB>
copied to clipboard
Press "Next"
Press "Save"
Step 10: Sign in #
In the previous step we've used the Google-generated key as signing key.
This changes the SHA-1 certifcate fingerprint to their own.
So, we need to copy that SHA1 key into our firebase configuration.
Goto https://play.google.com/console
Select your app
Goto Release > Setup > App signing
Find the SHA-1 certificate fingerprint in the "App signing key certificate" section and copy it.
Goto https://console.firebase.google.com
Select your project
Press "Project Overview" > "Settings (gear box)" and select "Project settings"
From the "General" tab > "Your apps" press "Add fingerprint" and paste the SHA-1 from step 4.
Step 11: Publishing overview #
Press the "Send n changes for review"
Congratulations. Now you just have to wait for approval. In our case this took 6h. You'll receive an email.
Chapter V. Deploy to apple store #
Step 1: Enroll for the Apple Developer Program. #
Goto https://developer.apple.com/programs/enroll/ and follow onscreen instructions to enroll for the Apple Developer Program.
Step 2: Create an app on App Store Connect #
https://appstoreconnect.apple.com/apps
Select '+' and select 'New app'
Specify new app details:
Platforms: iOS
Name: your app nickname, here Thoma5
Primary language: choose your language, we've chosen English (UK)
Bundle ID: select your App Bunble ID, here com.thoma5.thoma5ios
SKU: copy your bundle ID, here com.thoma5.thoma5ios
User Access: Full Access
Step 3: Provide App Information #
https://appstoreconnect.apple.com/apps
Select your app
Press General > App Information
Specify Category, here Education
Specify Content Rights, select 'No, it does not contain, show, or access third-party content'
Specify Age Ratings
select 'NONE' for all entries of 'APPLE CONTENT DESCRIPTION'
specify 'No, this app doesn't contain unrestricted web access'
specify 'No, this app doesn't contain instances of gambling'
Select 'Restrict to 17+'
Press 'save'
Step 4: Create a build archive #
Goto your android studio directory and run these statements
cd ios
flutter build ipa --no-tree-shake-icons
copied to clipboard
Step 5: Upload to App Store Connect #
Option 5.1: Use upload tool #
Create a key
https://appstoreconnect.apple.com
Press 'Users and Access'
Select 'Keys' tab
Press '+' to add a key
Enter a name, here Thomas
Select 'developer' as access
Press 'generate'
Press the 'download' button, then copy the file into your project directory/private_keys
Copy the Issuer ID from the page (near the top) and make note
Copy the KEY ID and make note
Issuer ID: ab1cde23-a1bc-a1bc-a1bc-ab1cde23
KEY ID: ABC1DE23FG
Private key directory: /Users/thomas/src/myprojects/apps/thomas5_app/ios/private_keys
Run the below command, change the your_api_key and your_issuer_id
xcrun altool --upload-app --type ios -f build/ios/ipa/*.ipa --apiKey your_api_key --apiIssuer your_issuer_id
copied to clipboard
MORE INFO
Creating API Keys for App Store Connect API
Option 5.2: Use transport app #
Install and open 'Apple Transport app' on your mac
Drag and drop the build/ios/ipa/*.ipa app bundle onto the 'Apple Transport app'
Step 6: Take screenshots #
Step 6.1: Create simulators #
To be able to create screenshots for app sumission, we need to create iOS simulators.
Open your project in xcode
From xcode, select menu Xcode > Open Developer Tool > Simulator
From the Simulator, select File > New Simulator and create simulators for the iOS simulator Device types listed below. Use one of the latest OS!
App Store Connect device type
iOS simulator Device type
iPhone 6.7"
iPhone 14 Pro Max
iPhone 6.5"
iPhone 11 Pro Max
Phone 5.5"
iPhone 8 Plus
iPad pro (6th gen) 12.9" Display
iPad Pro (12.9-inch) (6th generation)
iPad pro (2nd gen) 12.9" Display
iPad Pro (12.9-inch) (2nd generation)
Step 6.2 Create screenshots #
For each of the simulators created in the previous step, do this:
From the simulator application, run the simulator
From Android studio, select the simulator as the device, then press run
Press the camera button from the simulator and save the screenshot
Record the filenames
iOS screenshots: /src/.../thoma5_app/assets/screenshots\*.jpg
Close the simulator afterwards
Step 7: Create test user #
For submission to the Apple App Store, we need to provide a login and password. Create a test account on icloud and store login and password
Test icloud account: *****@icloud.com
Password: *****
Step 8: Provide App Privacy details #
https://appstoreconnect.apple.com/apps
Select your app
Select 'General' > 'App Privacy'
In Privacy Policy, press 'Edit'
Provide Privacy policy URL, here https://thoma5.com/#THOMA5_APP/8a75d3fa-d8e9-4ac8-9eb7-851010807502-policy
Press 'Get Started' and follow on-screen instructions / questions
Depending on the answers, you now might need to setup variuous data types in App Privacy
Press 'Publish' and confirm
Step 9: Pricing and Availability #
https://appstoreconnect.apple.com/apps
Select your app
Select 'General' > 'Pricing and Availability'
In Price Schedule, press 'Add Pricing' and select Base Country and Price, i.e. 0 and save
In App Availablity specify where you want your app to be available.
Step 10: Submit the app #
https://appstoreconnect.apple.com/apps
Select your app
Select "Prepare for Submission"
Upload iOS screenshots
Specify Description
Specify Keywords
Specify Support URL = your domain, prefixed with https://, here https://thoma5.com
Specify Marketing URL = your domain, prefixed with https://, here https://thoma5.com
In Build select the build you've uploaded in previous step
In App Review Information, specify sign-in required Test icloud account and Password
Press 'Save'
Press 'Add for Review'
Press 'Submit to App Review'
Chapter VI. Extend the app with other packages #
TODO
Include extra packages and run wizards. For example, for thoma5 we added:
eliud.registerPackage(ChatPackage.instance());
eliud.registerPackage(FeedPackage.instance());
See overview of and links to all currently known packages below.
Chapter VII. Write and integrate your own code / packages #
TODO
Appendix A. Overview packages #
The dependencies of a typical app #
A typical app, here Minkey, uses the following dependencies:
Links #
Direct dependencies #
eliud_core_helpers
eliud_core_main
eliud_core_model
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.