flutter: fcm ios push notifications doesn't work in release mode - flutter

I have bound my flutter-iOS app to firebase and i'm also using firebase-messaging and cloud functions for sending notifications via subscribing to topics, i'm using the APNs push notifications key of apple developer account. when i use the option runner>flutter run main.dart in release mode to build my app on my phone, fcm notifications doesn't work anymore, while it works in development mode, anyone can help me fix this?
this is my index.json code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var newData;
exports.messageTrigger = functions.firestore.document('notifications/{notificationsId}').onCreate(async (snapshot, context) => {
newData = snapshot.data();
const payload = {
notification: {
title: newData.title,
body: newData.body,
sound: 'default'
},
data: {
click_action: 'FLUTTER_NOTIFICATION_CLICK',
message: newData.title,
}
};
if (newData.language === 'english'){
await admin.messaging().sendToTopic('english', payload);
}
else if (newData.language === 'arabic'){
await admin.messaging().sendToTopic('arabic', payload);
}
else if (newData.language === 'kurdish'){
await admin.messaging().sendToTopic('kurdish', payload);
}
});
hence package.json:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "10"
},
"dependencies": {
"firebase-admin": "^8.10.0",
"firebase-functions": "^3.6.1"
},
"devDependencies": {
"eslint": "^5.12.0",
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.2.0"
},
"private": true
}

My project got the same issue. Combined two solutions I found, it finally works. (firebase_messaging 7.0.3)
As for debug mode, you don't need these.
Step 1: Edit AppDelegate.swift
import UIKit
import Flutter
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
GeneratedPluginRegistrant.register(with: self)
application.registerForRemoteNotifications()
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Step 2: Edit ios/Runner/Info.plist. Add this:
<key>FirebaseAppDelegateProxyEnabled</key>
<string>NO</string>

After update firebase_messaging to 7.0.0 I had the same problem. I added application.registerForRemoteNotifications() in my AppDelegate.swift and it worked!

I tried many ways. I did deep research, when i give up i checked my Xcode Settings and i saw under Signing&Capabilities -> Debug -> Notification added but Signing&Capabilities -> Release I didn't add.
so i added capability and it worked look this

I have the same issue. Looks like iOS release require additional notification params
To check that notification works you could try to send message directly from the firebase console.
Cloud Messaging -> Send your first message -> Enter notification title and text -> Send test message -> Enter your device token -> Test
To obtain device token you can use print(await FirebaseMessaging().getToken());
To check release logs connect the device and open Xcode -> Window -> Devices and Simulators -> Open Console
If it works you could try to add this params:
const payload = {
notification: {
title: newData.title,
body: newData.body,
sound: 'default'
},
data: {
click_action: 'FLUTTER_NOTIFICATION_CLICK',
message: newData.title,
},
apns: {
headers: { "apns-priority": "5" },
payload: {
aps: {
contentAvailable: true,
category: "NEW_MESSAGE_CATEGORY"
}
}
},
};
But I'm not sure which param helps: "apns-priority" or contentAvailable.

Related

Push Notifications with RealmDB (MongoDB) and react-native-push-notification

I am using Realm for an already quite elaborate application and I want to finish it by adding push notifications. I have already installed react-native-push-notification and make it works with FCM (Firebase Cloud Messaging).
On the client side, I do receive test notifications from Firebase.
I then configured the push notifications in the Realm console by adding the Sender Id and the API Key.
The problem is that when I send a notification from Realm it ends up in "sent", but absolutely nothing happens, no logs in the Realm console, nothing on the Firebase side and nothing on the client side.
The documentation on push notifications for Realm is really limited and I can't quite figure out what to do. The documentation is mainly directed for IOS and Android.
That's my code in index.js:
import PushNotificationIOS from '#react-native-community/push-notification-ios';
import PushNotification from 'react-native-push-notification';
PushNotification.configure({
onRegister: function (token) {
console.log('TOKEN:', token);
},
onNotification: function (notification) {
console.log('NOTIFICATION:', notification);
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
onAction: function (notification) {
console.log('ACTION:', notification.action);
console.log('NOTIFICATION:', notification);
},
onRegistrationError: function (err) {
console.error(err.message, err);
},
permissions: {
alert: true,
badge: true,
sound: true,
},
popInitialNotification: true,
requestPermissions: true,
});
PushNotification.createChannel(
{
channelId: 'fcm_fallback_notification_channel',
channelName: 'FCM CHANNEL',
channelDescription: 'Description test',
},
created => console.log(`CreateChannel returned '${created}'`),
);
PushNotification.localNotification({
channelId: 'fcm_fallback_notification_channel',
vibrate: true,
vibration: 300,
playSound: true,
soundName: 'default',
});
Does anyone know of a tutorial or something that could give me some additional information?
So to make it work, you'll have to add this line in index.js:
PushNotification.subscribeToTopic('topic-id-in-realm-console');
And use the same topic id in Realm console:
It ends up with something like this (index.js):
import PushNotificationIOS from '#react-native-community/push-notification-ios';
import PushNotification from 'react-native-push-notification';
PushNotification.configure({
onRegister: function (token) {
console.log('TOKEN:', token);
},
onNotification: function (notification) {
console.log('NOTIFICATION:', notification);
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
onAction: function (notification) {
console.log('ACTION:', notification.action);
console.log('NOTIFICATION:', notification);
},
onRegistrationError: function (err) {
console.error(err.message, err);
},
permissions: {
alert: true,
badge: true,
sound: true,
},
popInitialNotification: true,
requestPermissions: true,
});
PushNotification.subscribeToTopic('topic-id-in-realm-console');// <== HERE
On client:

Cannot test a native Android app using codeceptJS

I have created a codeceptJS project by following the mobile testing setup steps located here: https://codecept.io/mobile/#setting-up
So far, I'm unable to test any apps via simulator; I instead get the following error:
1) login
I should be able to login with the correct username and password:
>> The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource <<
at Object.getErrorFromResponseBody (node_modules/webdriver/build/utils.js:189:12)
at NodeJSRequest._request (node_modules/webdriver/build/request/index.js:157:31)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
I have verified my appium config using appium-doctor, and there are no issues found.
My codecept.conf.js is as follows:
const path = require('path');
const { setHeadlessWhen } = require('#codeceptjs/configure');
// turn on headless mode when running with HEADLESS=true environment variable
// export HEADLESS=true && npx codeceptjs run
setHeadlessWhen(process.env.HEADLESS);
exports.config = {
tests: './*_test.js',
output: './output',
helpers: {
Appium: {
platform: 'Android',
device: 'emulator',
desiredCapabilities: {
avd: 'Pixel_5_API_28',
app: path.resolve('./sample_apps/Android.apk'),
appActivity: 'com.swaglabsmobileapp.MainActivity'
}
},
},
include: {
I: './steps_file.js'
},
bootstrap: null,
mocha: {},
name: 'appium-codecept-android-POC',
plugins: {
pauseOnFail: {},
retryFailedStep: {
enabled: true
},
tryTo: {
enabled: true
},
screenshotOnFail: {
enabled: true
}
}
}
And here's my package.json as created by codeceptjs init:
{
"name": "appium-codecept-android-POC",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"codeceptjs": "^3.0.7",
"webdriverio": "^7.9.0"
}
}
Finally, my test file is as follows:
Feature('login');
Scenario('I should be able to login with the correct username and password', ({ I }) => {
setTimeout(() => {
I.see('Username');
}, 3000);
I.click('//android.widget.EditText[#content-desc="test-Username"]');
I.fillField('//android.widget.EditText[#content-desc="test-Username"]', 'standard_user');
I.click('//android.widget.EditText[#content-desc="test-Password"]');
I.fillField('//android.widget.EditText[#content-desc="test-Password"]', 'secret_sauce');
I.click('//android.view.ViewGroup[#content-desc="test-LOGIN"]');
I.waitForElement('//android.view.ViewGroup[#content-desc="test-Cart drop zone"]/android.view.ViewGroup/android.widget.TextView', 3)
I.dontSeeElement('//android.view.ViewGroup[#content-desc="test-Error message"]/android.widget.TextView');
});
Scenario('I should not be able to login with an incorrect username or password', ({ I }) => {
setTimeout(() => {
I.see('Username');
}, 3000);
I.click('//android.widget.EditText[#content-desc="test-Username"]');
I.fillField('//android.widget.EditText[#content-desc="test-Username"]', 'bob');
I.click('//android.widget.EditText[#content-desc="test-Password"]');
I.fillField('//android.widget.EditText[#content-desc="test-Password"]', 'secret_sauce');
I.click('//android.view.ViewGroup[#content-desc="test-LOGIN"]');
I.waitForElement('//android.view.ViewGroup[#content-desc="test-Cart drop zone"]/android.view.ViewGroup/android.widget.TextView', 3)
I.dontSeeElement('//android.view.ViewGroup[#content-desc="test-Error message"]/android.widget.TextView');
});
Scenario('I should be able to see details', ({ I }) => {
// login
setTimeout(() => {
I.see('Username');
}, 3000);
I.click('//android.widget.EditText[#content-desc="test-Username"]');
I.fillField('//android.widget.EditText[#content-desc="test-Username"]', 'standard_user');
I.click('//android.widget.EditText[#content-desc="test-Password"]');
I.fillField('//android.widget.EditText[#content-desc="test-Password"]', 'secret_sauce');
I.click('//android.view.ViewGroup[#content-desc="test-LOGIN"]');
I.waitForElement('//android.view.ViewGroup[#content-desc="test-Cart drop zone"]/android.view.ViewGroup/android.widget.TextView', 3)
// should be able to click a label to see details
I.click('(//android.widget.TextView[#content-desc="test-Item title"])[2]');
I.seeElement('//android.view.ViewGroup[#content-desc="test-Description"]/android.widget.TextView[2]');
I.click('//android.view.ViewGroup[#content-desc="test-BACK TO PRODUCTS"]');
});
I'm at a loss here, as I haven't done anything except follow the setup instructions. Executing against ios works; it is only the android execution that fails. Appium is installed and running, env vars are set, etc. Any help would be appreciated, as this could be a deal breaker for me in terms of whether or not I can use codeceptjs. I love the project and really want to use it, but I must be able to test both ios and android native apps.
One final note: If anyone wants to try this config, the app I am using for the above test can be found here: https://github.com/saucelabs/sample-app-mobile/releases/download/2.7.1/Android.SauceLabs.Mobile.Sample.app.2.7.1.apk

An error was encountered with the requested page AWS User Pool with Swift

I'm trying to use AWS Cognite User Pool to login with AppleId for iOS application. We couldn't use federated identity, I must use User Pool. While login User Pool, I use hosted UI in iOS application. I had set up service configuration on Aws and iOS application seen below. When I tried to login User Pool, I take a 'An error was encountered with the requested page ' error in WebView.
let hostedUIOptions = HostedUIOptions(identityProvider: "SignInWithApple")
AWSMobileClient.default().showSignIn(navigationController: self.navigationController!, hostedUIOptions: hostedUIOptions) { (userState, error) in
if let error = error as? AWSMobileClientError {
print(error.localizedDescription)
}
if let userState = userState {
print("Status: \(userState.rawValue)")
}
}
AWSConfiguration.json
{
"IdentityManager": {
"Default": {}
},
"CognitoUserPool": {
"Default": {
"PoolId": "eu-west-1_rsPBto6Jx",
"AppClientId": "6atv5t6egacicor9cioXXXXXX",
"AppClientSecret": "171du4k8rf098lmnuvhm2h3o1umqcdfnngcj84tc304moXXXXXXXX",
"Region": "us-east-2"
}
},
"Auth": {
"Default": {
"OAuth": {
"WebDomain": "XXXXX.auth.us-east-2.amazoncognito.com",
"AppClientId": "6atv5t6egacicor9cioXXXXXX",
"AppClientSecret": "171du4k8rf098lmnuvhm2h3o1umqcdfnngcj84tc304moXXXXXXXX",
"SignInRedirectURI": "myapp://",
"SignOutRedirectURI": "myapp://",
"Scopes": ["openid", "email","aws.cognito.signin.user.admin","profile","phone"]
}
}
}
}
How can I solve this problem?
Solution
When I add callback url in consol myapp://sigout, problem was solved.It is my mistake.

ionic react local notifications with capacitor not working

I am trying to implement local notifications using capacitor.
first I installed plugin using below commands,
npm install #ionic-native/local-notifications
npm install cordova-plugin-local-notification
Then in my .js file, I did add below code
import { Plugins } from '#capacitor/core';
And
scheduleNotification = () => {
Plugins.LocalNotifications.schedule({
notifications: [
{
title: "Title",
body: "Body",
id: 1,
schedule: { at: new Date(Date.now() + 1000 * 5) },
sound: null,
attachments: null,
actionTypeId: "",
extra: null
}
]
});
console.log('scheduled notifications');
}
I tried everything, but I can't see any local notification on my iPhone 6s running iOS 12.
When I check Xcode logs, I can see Scheduled notification with id 1.
cordova-plugin-badge (0.8.8)
cordova-plugin-device (2.0.3)
cordova-plugin-local-notification (0.9.0-beta.2)
I had the same issue, I set my notification id with an UUID but it did not work. I solved it in setting my notification id with new Date().getTime().
It was issue regarding id pass in your result.
PushNotifications.addListener('pushNotificationReceived',
async (notification: any) => {
console.log(notification);
const notifs = await LocalNotifications.schedule({
notifications: [
{
title: notification.title,
body: notification.body,
id: new Date().getTime(),
schedule: { at: new Date(Date.now() + 1000 * 5) },
sound: this.platform.is("android")
? "file://sound.mp3"
: "file://beep.caf",
attachments: null,
actionTypeId: "",
extra: notification
}
]
});
}
);
For the ios, I think, it is not supported yet.
For android, try to request permission.

Change FCM sender ID

I had setup push notification in my App using the following command:
ionic cordova plugin add phonegap-plugin-push --variable SENDER_ID="1234567890"
Which added the below code to my package.json
"phonegap-plugin-push": {
"SENDER_ID": "1234567890"
}
Now the issue is I have to change this sender ID to something else and I want to know how to do this, also I have the below code in my project to set up the options for push notification.
const options: PushOptions = {
android: {
senderID: '218580369028'
},
ios: {
alert: 'true',
badge: true,
sound: 'false'
},
windows: {},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
}
};
Is this as simple as just replacing the sender ID with what I want in package.json and in the above code. Or do I have to do something else for this. Any help is greatly appreciated.