Flutter can not upload File to Firebase Storage - firebase

I am simply trying to upload an image using Firebase CloudFirestore/Storage. This is my method for it:
Future<void> uploadFile() async {
File file = File(croppedImagePath);
try {
int randomNumber = Random().nextInt(10000);
String imageLocation = 'images/image$randomNumber.jpg';
await FirebaseStorage.instance.ref(imageLocation).putFile(file); // <- crash
_addPathToDatabse(imageLocation);
} on FirebaseException catch (e) {
// e.g, e.code == 'canceled'
print(e.message);
}
}
but this crashes with:
Exception has occurred.
MissingPluginException (MissingPluginException(No implementation found for method Task#startPutFile on channel plugins.flutter.io/firebase_storage))
This is what I added in pubspec.yaml :
firebase_core: ^1.3.0
cloud_firestore: ^2.3.0
firebase_storage: ^9.0.0
I tried running flutter clean and also restarted the project several times... What am I missing here? Why is it not working?

I recommend that you check if the file is correct, you can also try converting your file to bytes.

after running Flutter clean, restarting my pc and deleting my derived data it is working again...

Related

How to set Firebase Database URL (Unity)

I'm trying to create a login with Facebook with Firebase.
My login function is:
public void FacebookLogin()
{
var perms = new List<string>() { "public_profile", "email" };
FB.LogInWithReadPermissions(perms, AuthCallback);
if (FB.IsLoggedIn)
{
string aToken = Facebook.Unity.AccessToken.CurrentAccessToken.UserId;
Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
Firebase.Auth.Credential credential = Firebase.Auth.FacebookAuthProvider.GetCredential(aToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task => {
if (task.IsCanceled)
{
Debug.LogError("SignInWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithCredentialAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
}
}
My problem is the warning "Database URL not set in the Firebase config.", followed by a SignInWithCredentialAsync error (System.AggregateException).
How can I change the URL in Firebase config? Where is this Firebase config located?
I'm a newbie in coding, thanks for the support.
I should manage to link all the Id app, Oauth etc correctly( i hope so), I believe the problem is caused by the empty URL for firebase db.
firebaser here
There is a bug in the Firebase games SDKs at the moment, which makes it require that a databaseURL value is specified in the google-services.json and/or google-services-info.plist files. Unfortunately that key is not present anymore, unless you actually use the Realtime Database.
The easiest might be to:
Create a Realtime Database instance in the Firebase console.
Download the updated configuration files and add them to your project again.
Update: I just spotted that the issue on Github also mentions a workaround for the problem.

Firebase FCM onLaunch code not running functions when clicking on notification

I am using FCM to deliver notifications that once clicked take the user to a specific page on the app. Currently, the onMessage and onResume functions work perfectly fine but on launch does not.
I include the
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
and
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
because I am also using flutter local notifications.
I have already tried removing these lines but they do not make a difference.
Ok so the problem I had was that when the on launch code fires my app was loading other data and functions e.t.c when on the loading splash page. What I had to do was when on launch fires I saved the notification in a variable. Then I executed the code I wanted after the splash init was finished
onLaunch: (Map<String, dynamic> notification) async {
print("onLaunch: $notification");
///Saving the notification to use once the rest of the initialising and
///Loading is done
launchNotification = notification;
},
Then once the loading and the initialising of other processes had finished I ran the ran this function
onLaunchFunction() async {
await Future.delayed(Duration(milliseconds: 100));
Map tempNotification = launchNotification;
if (launchNotification != null) {
launchNotification = null;
///The rest of the function
}
}
I added an a future delayed just to make sure that my code would run whilst the initialising. This may not be needed

'Unable to fetch remote config. Cached or default values will be 'used' flutter

I have setup firebase config for flutter
According to documentation https://pub.dev/packages/firebase_remote_config#-readme-tab-
My key is
then I have Published also then i tried following code and it will return
'Unable to fetch remote config. Cached or default values will be ''used'
could you please point issue
I have tried those also
Firebase Remote Config - Initial fetch return local default values
Remote config in Flutter app throws exception on fetch
try {
remoteConfig.getString('welcome')[![enter image description here][1]][1]
// Using default duration to force fetching from remote server.
await remoteConfig.fetch(expiration: const Duration(seconds: 0));
await remoteConfig.activateFetched();
} on FetchThrottledException catch (exception) {
// Fetch throttled.
print(exception);
} catch (exception) {
print(
'Unable to fetch remote config. Cached or default values will be '
'used');
}
This worked fine for me,
await remoteConfig.ensureInitialized();
it's work for me
FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.instance;
initializeRemote() async {
// remoteConfig = await setupRemoteConfig();
//!- must be active firebase remote config
bool updated = await remoteConfig.fetchAndActivate();
if (updated) {
print("found");
// the config has been updated, new parameter values are available.
} else {
print("not print");
// the config values were previously updated.
}
await remoteConfig.ensureInitialized().then((value) async {
print("remote value -> ${await remoteConfig.getString("app_version")}");
});
}
Usually when you fight these problems, in the end, everything gets mixed up. I think after the post you could already see the configured value, but the error occurs when querying another parameter name. Add the following line to see the actual error you are getting.
print('EXCEPTION: $exception');
try {
await remoteConfig.fetch(expiration: const Duration(seconds: 0));
await remoteConfig.activateFetched();
String forceUpdateCurrentVersion =
remoteConfig.getString('force_update_current_version');
double newVersion =
double.parse(forceUpdateCurrentVersion.trim().replaceAll(".", ""));
if (newVersion > currentVersion) {
_showVersionDialog(context);
}
} on FetchThrottledException catch (exception) {
// Fetch throttled.
print(exception);
} catch (exception) {
print('EXCEPTION: $exception');
print('Unable to fetch remote config. Cached or default values will be '
'used');
}
Just put value don't put braces for Default value
For Example
Then use below code in flutter
remoteConfig.getString('IT_');
If you are using Android emulator, ensure it has Google play services enabled.

How to integrate remote config to a flutter app?

I have to integrate firebase remote config to my flutter app. From the searches in various sites, I couldn't find the complete solution.
class RemoteConfigurartion{
Future<RemoteConfig> setupRemoteConfig() async {
String value =null;
final RemoteConfig remoteConfig = await RemoteConfig.instance;
remoteConfig.setConfigSettings(RemoteConfigSettings(debugMode: false));
remoteConfig.setDefaults(<String, dynamic>{
'riddle': "off",
});
try {
// Using default duration to force fetching from remote server.
await remoteConfig.fetch(expiration: const Duration(seconds: 0));
await remoteConfig.activateFetched();
} on FetchThrottledException catch (exception) {
// Fetch throttled.
print(exception);
} catch (exception) {
print(
'Unable to fetch remote config. Cached or default values will be '
'used');
}
return remoteConfig;
}
}
This is what I found already. This the result I'm getting:
No implementation found for method RemoteConfig#instance on channel plugins.flutter.io/firebase_remote_config
But I have added all the plugins in the pubspec.yaml and in android gradle folder
Can anyone help me to find out a complete solution to integrate remote config to a flutter app?
Make sure that firebase_core is initialized, and for Android, google-services.json should be in the app folder. Aside from that, there doesn't seem to be any issues on your code. You might've missed some steps during set up.
If you've just added the plugins, it's best to run the app using restart instead of hot reload to ensure that all recently added plugins is included in the build.

Firebase FCM notification received in iOS simulator but as GCM(?) on real iOS device in flutter app

edit: it is supposed to look like it does on the device log, according to Firebase support
I am adding push notifications via FCM to my Flutter app, but the message format is very different on the iOS Simulator vs. my iPhone 5s.
When receiving a push notification from the Firebase console to an active/opened app.
Problem: What do I need to do to make sure the real device receives the message in the correct format?
Log from Simulator (iPhone XR, 12.2) (looks like in the official code examples):
onMessage: {
from: 123000000000,
collapse_key: com.mydomainnamehere,
notification: {
body: Lorem ipsum,
title: Title,
e: 1,
tag: campaign_collapse_key_9876543210011223344
}
}
Log from real device (iPhone 5s, 12.2) (can't find any references online to this):
onMessage: {
google.c.a.c_l: notif_name,
google.c.a.e: 1,
aps: {
alert: {
title: Title,
body: Lorem ipsum
}
},
gcm.n.e: 1,
google.c.a.c_id: 9876543210011223344,
google.c.a.udt: 0,
gcm.message_id: 1234567800998877,
google.c.a.ts: 1234567800
}
The notification is sent from the Firebase console to all devices, the logs are taken from the same notification (but I anonymized the id's).
The Device and Simulator is running the same Flutter code from Android Studio, at the same time.
Parts of my pubspec.yaml that refers to FCM
firebase_core: ^0.4.0+1
firebase_auth: 0.11.1
cloud_firestore: ^0.11.0+2
firestore_ui: ^1.4.0
firebase_messaging: ^5.0.2
Software and SDK Versions
Flutter Channel dev, v1.8.4,
Mac OS X 10.14.5,
Android SDK version 28.0.3,
Xcode 10.2.1,
Android Studio version 3.4
Flutter message-handling code
void initState() {
super.initState();
if (Platform.isIOS) {
iosSubscription = _fcm.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
print("FCM settings received: $settings");
});
_fcm.requestNotificationPermissions(IosNotificationSettings());
}
_fcm.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
);
getFcmToken();
}
void getFcmToken() async {
var token = await FirebaseMessaging().getToken();
print("Token $token");
}
I was expecting that the JSON format would be the same on both the simulator and a real device. But the real device isn't even receiving all of the notification.
According to Firebase support, we should not be able to get push notifications in the simulator, and they say that the gcm-format above is indeed the correct one.
The solution is to always use key-value pairs as stated in the answer to this previous question FCM - Get Message Label
For those who still struggle with this, there seems an alternative solution.
While the structure of the data can be different in various conditions (iOS/Android or Real device/Simulator), the key names of those essential parts of the data are considered to be unique no matter how deeply nested: "title" and "body". Therefore, extracting the values of those 'title' and 'body' entries might solve the problem.
//get title value from the message load (whether data or push)
String _title = _findFirstKeyValue(message, 'title');
The following is a recursive function to get the first matching entry from the message Map.
String _findFirstKeyValue(Map data, String targetKey) {
for (final k in data.keys) {
final v = data[k];
if (v is Map) { // go deeper if the value is still a kind of Map
final String _temp = _findFirstKeyValue(v, targetKey);
if (_temp != '') return _temp;
} else { // when the value is primitive Key-Value pair
if (k.toString().toLowerCase() == targetKey.toLowerCase()) {
return v.toString();
}
}
}
return '';
}
Note that return will not be fired if you use data.forEach rather than ordinary for loop.

Resources