Fedi is open-source client for Pleroma and Mastodon social networks written using Flutter.
Pleroma and Mastodon are parts of Fediverse (decentralized social network). The main idea of Fediverse - nobody owns Fediverse. Anybody can run their server instance and use it to communicate with other people.
So Fedi is an open-source mobile client for social networks and has features similar to Twitter.
Follow us on Fediverse fediapp@fedi.app
Always show NSFW
or Auto-load media content
Feel free to open issues if you have suggestions
Fedi doesn't use any special analytics service to track users. However Fedi uses Firebase services for PushNotifications(optional) and CrashReporting(optional).
You can completely remove Firebase via manual building from source.
Fedi gathers crashes and non-fatal errors to make app more stable.
Push notifications are implemented via toot-relay-fcm server
PushRelayFCM is Ruby on Rails server which handles web pushes and relays them to FCM.
From 2.5.0
version Fedi uses PushRelayFCM mode without decryption on server-side. So all private data is safe.
PushRelayFCM and Fedi can work in two modes:
2.5.0
and newer) - relay simple proxy encrypted messages2.5.0
) -decrypt messages and have access to notification content and user access_token
. It is not used from 2.5.0
version, but is still supported in Fedi(see below why you still may want to use it).(Used in AppStore/GooglePlay versions from 2.5.0
)
/api/v1/push/subscription
with subscription[endpoint]
set to relay server URLSince PushRelayServer doesn't know private decryption keys, it can't access any private data.
awesome_notifications
notification
(FCM calls it data message). Read awesome_notifications
and firebase_messaging
documentation for details. Fedi uses :mutable_content=>true,
:content_available=>true,
:priority=>"high",
to increase delivery priorityBecause it is hard to implement with Flutter. There are no 3rd party Flutter libraries to decrypt ECDH
p256v1
by now.
It is possible to decrypt it in Kotlin/Swift and it will be done in the future.
(It is not used in AppStore/GooglePlay versions from 2.5.0
)
/api/v1/push/subscription
with subscription[endpoint]
set to relay server URLtitle
, body
and access_token
access_token
is sensitive data. It is possible to login into your account if someone knows access_token
notification.title
and notification.body
, which has higher priority than message without notification.title
& notification.body
fields. Actually it is more affects iOS, than Android. Read awesome_notifications
and firebase_messaging
documentation for details.Without server-side decryption way
awesome_notifications
App uses flutter_localization
API bundle with Flutter SDK.
It uses .arb
files located in lib/l10n
and generates .dart
classes in /lib/generated/
folder.
After you make changes in .arb
files you should do additional actions to regenerate Dart classes
flutter intl
pluginflutter intl
packageprovider
StatelessWidget
and async UI update via StreamBuidler
and BehaviourSubject
& StreamController
in controller classesWidgets
in small sub Widgets
with const
constructor(for better performance) if possibleprovider
Repository
pattern. Almost all network data is cached in local SQLite database. UI always displays data from single source. It may be network-only or from database(if data is cached). Doesn't cache and merge data in memory to achieve data consistencyaccount_follower_account_cached_list_bloc_impl.dart
and AccountFollowerAccountCachedListBloc
interfaces
for Bussines Logic
and Services
I
to implementation class name. AccountFollowerAccountCachedListBloc
is implementation and IAccountFollowerAccountCachedListBloc
is interfaceTo build Fedi you need to specify Flutter version in .fvm/fvm_config.json
field flutterSdkVersion
.
You can achieve this by specifing your system Flutter version by using flutter version $version
or using FVM
Fedi uses Flutter Version Management to specify Flutter version to build app.
FVM also helps manage several SDK's versions on local machine
Config is already done, so you just run fvm install
in repo folder and configure IDE to use .fvm/flutter_sdk
folder instead of system Flutter SDK.
To use flutter version specified in .fvm/fvm_config.json
you should prepend fvm
like fvm flutter install
More info you can found in FVM documentation
There a lot of useful comand line actions automated by melos commands.
Run fvm flutter pub global run melos run
to see all possible melos actions
moor
is SQLite ORM. For local data cache & offline mode supporthive
is secure and fast storage for preferencesprovider
for Dependency Injectionflutter_html
for content renderingrxdart
for reactive programmingpedantic
& dart_code_metrics
for better code analyzing. See analysis_options.yaml
for enabled rulesflutter_cache_manager
for media cachingflutter_intl
for localization via .arb
filespull_to_refresh
) and Platform-dependent(like permission_handler
) librariesflutter_config
to config via .env filesfirebase_messaging
and awesome_notifications
for push notificationsYou can find full list in pubspec.yaml
where each library has comment why it's used
git clone https://github.com/Big-Fig/Fediverse.app
cd Fediverse.app
Install Flutter version used by this project
fvm install
Link multi-module project dependencies
fvm flutter pub global activate melos
fvm flutter pub global run melos bootstrap
Copy config for prod
and dev
flavors
cp env_example.env env_prod.env
cp env_example.env env_dev.env
In Example config you can find out how to disable some features like Push notifications.
To enable all features you should change app id, create Firebase project, and edit config file.
fvm flutter pub get
fvm flutter run --flavor dev
or
fvm flutter run --flavor prod
File->Preferences->Languages & Frameworks->Flutter
to <Project_Root>/.fvm/flutter_sdk
File->Preferences->Languages & Frameworks->Dart
).It should be <Project_Root>/.fvm/flutter_sdk/bin/cache/dart-sdk
prod
or dev
) in Run Configurations
Run->Edit configurations
Pub get
in IDE or run fvm pub get
in terminalThere are two main flavors.
Implementation details: Build flavors in Flutter (Android and iOS) with different Firebase projects per flavor
Is used for production builds
Is used for development builds. You can use only prod flavor if you don't need special config for development
Main purpose of config files is to exclude sensitive data from source control and quickly enable/disable and config some features like Push Notifications
Build script uses config from project root folder depends on flavor, so to build app you should have next files in root folder
env_prod.env
env_dev.env
Those files are excluded from source control.
You can find all possible config variables(with comments) at env_example.env
fvm flutter pub global run melos run clean
fvm flutter clean
or flutter clean
if you don't use FVM./gradlew clean
in android folderProduct->Clean
in XCodeFile(or Android Studio on Mac)->Invalidate caches & Restart
in Android StudioSometimes it is also needed to clear iOS pods
fvm flutter pub global run melos run clean:ios
cd ios
rm -rf Pods
rm Podfile.lock
pod install
Sometimes you change package version in pubspec.yaml
run pub get
but version is not changed
rm pubspec.lock
rm .flutter-plugins
rm .flutter-plugins-dependencies
rm .packages
rm -rf .dart_tool
pub get
Sometimes when you change package version in pubspec.yaml
and after pub get
version is not changed.
You can check pubspec.lock
to see if version is changed.
That may happen when you specify version bounds like >=1.0.0 <2.0.0
or ^1.0.0
which are the same.
See Version constraints in official docs.
rm pubspec.lock
rm .flutter-plugins
rm .flutter-plugins-dependencies
rm .packages
rm -rf .dart_tool
pub get
Fedi specifies explicitly version like 1.0.0
to avoid such issues.
However, that may cause dependencies version conflict
Changing App ID is required if you want to setup own PushRelayFCM server and pushes via your Firebase project for FCM.
It is also useful if you want to have several app versions installed on one device
Unfortunately, it is not possible to use APP_ID from config in all places in Gradle and XCode project files. So in some places ID is hardcoded
So, If you want to change app id from com.fediverse.app
for prod
and from com.fediverse.app2
for dev
you should manually change them (in addition to changing id in .env
files)
Actually, you should run Find and Replace com.fediverse.app
with your package name on ios
and android
folders. And rename folders at android/app/src/main/kotlin
However, it may cause strange build errors. So you may need full clean
If you still have errors please explore App ID things in the next docs:
flutter_config
firebase_core
firebase_crashlytics
firebase_messaging
receive_sharing_intent
receive_sharing_intent
lib requires to add group.fork of receive_sharing_intent
with custom group ids support.Fedi uses group fediverse.app
for prod
and com.fediverse.app2
for dev
Signing config is required to make release
builds
Generate key via Tutorial and put it in android/key/key.jks
(exclude from source control)
Create android/key.properties
(exclude from source control) file with next template.
storePassword=pass1
keyPassword=pass2
keyAlias=keyName
storeFile=../key/key.jks
Follow official tutorial
To use Firebase service you should generate files from your Firebase project page and put them in the project.
Don't forget to enable it in .env
file
FIREBASE_ENABLED=false
google-services.json
Put google-services.json
to folder depends on used flavor
android/app/src/dev
android/app/src/prod
GoogleService-Info.plist
Put GoogleService-Info.plist
to folder depends on used flavor
ios/config/dev
ios/config/prod
For more details see
To enable Push notifications you should
App ID and FCM server key(so and PushRelayFCM instance) are connected. It is not possible to use one PushRelayFCM instance with several App IDs and vice versa
On/Off via .env. Firebase Core integration is required
PUSH_FCM_ENABLED=false
Is required if PUSH_FCM_ENABLED=true
PUSH_SUBSCRIPTION_KEYS_P256DH
User agent public key. Base64 encoded string of public key of ECDH key using prime256v1 curve.
PUSH_SUBSCRIPTION_KEYS_AUTH
Auth secret. Base64 encoded string of 16 bytes of random data.
More info in Mastodon docs and PushRelayFCM server docs
PUSH_FCM_RELAY_URL=https://pushrelay.example.com/push/
PUSH_SUBSCRIPTION_KEYS_P256DH=BEpPCn0cfs3P0E0fY-gyOuahx5dW5N8qu
PUSH_SUBSCRIPTION_KEYS_AUTH=T5bhIIyre5TDC
On/Off via .env. Firebase Core integration is required
CRASHLYTICS_ENABLED=false
Used to catch errors on client-side with error description and stackTrace
You should enable Firebase support and change config variable in .env file to enable crash reporting
Uses version from pubspec.yaml
By default Flutter project config it should use version from pubspec.yaml
,
However, sometimes it causes strange iOS build errors(version is not changed but should be).
So, Fedi requires a manual increasing version code & name in Runner
and Share Extension
targets.
XCode project has additional ShareExtension module required by receive_sharing_intent
to handle income share events.
It is also important to add Target
and ShareExtension
to the same group ID.
assets/server_list.txt
is taken from tateisu/SubwayTooter