Flutter - Get Array in Firebase Messaging - firebase

In Flutter i try to get array in new firebase_messaging 10.0.0 like this
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:pushtest/functions/alert_messages.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:pushtest/constant/constant.dart' as Constants;
class PushNotifications {
FirebaseMessaging firebaseMessaging;
initNotifications() {
firebaseMessaging.requestPermission();
firebaseMessaging.getToken().then((token) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('firebaseToken', token);
});
}
configuration(scaffold, location) {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
var noti;
message as Map;
if (Platform.isIOS) {
noti = message['message'];
} else {
noti = message['data']['message'];
}
if (location == 'navigation') {
Messages.alert(scaffold.currentContext, noti);
} else {
Constants.message = noti;
}
return null;
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
var noti;
if (Platform.isIOS) {
noti = message['message'];
} else {
noti = message['data']['message'];
}
Constants.message = noti;
return null;
});
}
}
Problem: When i try to do
noti = message['message'];
Return
The operator '[]' isn't defined for the type 'RemoteMessage'. Try
defining the operator '[]'.
So what is the proper way to get array elements with listen functions?

If you are sending data messages then do:
noti = message.data['message'];

Related

SpyOn new InjectFirebaseAdmin from 'nestjs-firebase' error

i'm testing new InjectFirebaseAdmin from 'nestjs-firebase', i try to mock the function thats return me a verifyidToken but with out succes.
injectUser.ts
import { FirebaseAdmin, InjectFirebaseAdmin } from 'nestjs-firebase';
#Injectable()
export class InjectUser implements NestMiddleware {
constructor(
private readonly usersService: UsersService,
#InjectFirebaseAdmin() private readonly firebase: FirebaseAdmin // private firebaseAuth: FirebaseAuthenticationService
) {}
extractTokenFromHeaders(headers: IncomingHttpHeaders): string | undefined {
return headers.authorization?.split('Bearer ')[1];
}
async use(
req: AuthenticatedRequest,
res: Response,
next: () => void
): Promise<void> {
const token = this.extractTokenFromHeaders(req.headers);
if (token !== undefined) {
try {
const decodedToken = await this.firebase.auth.verifyIdToken(token);
req.uuid = decodedToken.uid;
} catch (error) {
throw isUnauthorizedHttpException();
}
const user = await this.usersService.getUserInfoFromAuthenticationId(
req.uuid
);
if (user) {
req.user = user;
}
}
next();
}
}
I would like to know how can i mock this function ? i use to try whith moduleRef.get(InjectFirebaseAdmin) but my spyOn function but i got this error : TypeError: Cannot read property 'auth' of undefined
Thanks for helping me

how to access http local woocommerce api localhost through flutter

I am trying to create a flutter application using woocomerce API.
for that woocommerce i have created in my localhost
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:ecommerce_store/config.dart';
import 'package:ecommerce_store/models/customer.dart';
class APIService {
Future<bool> createCustomer(CustomerModel model) async {
var authToken = base64.encode(
utf8.encode(Config.key + ":" + Config.sceret),
);
bool ret = false;
try {
var response = await Dio().post(
Config.url + Config.customerURL,
data: model.toJson(),
options: Options(headers: {
HttpHeaders.authorizationHeader: 'Basic $authToken',
HttpHeaders.contentTypeHeader: 'application/json'
}),
);
if (response.statusCode == 201) {
ret = true;
}
} on DioError catch (e) {
if (e.response?.statusCode == 401) {
ret = false;
} else {
ret = false;
}
// print(e);
}
return ret;
}
}
but when I try to do post-operation am getting
{
"code": "woocommerce_rest_cannot_view",
"message": "Sorry, you cannot list resources.",
"data": {
"status": 401
}
}
I saw that to access localhost API we need to use oauth1 but can anyone help me how to convert basic auth to oauth1
Thank you very much in advance

Firebase storage download audio files in React Native

I'm using firebase/storage to set up audio file downloading/uploading. I have the audio file in my firestore storage already.
With the following code, I am able to get the download URL of the specific file:
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/storage';
static async downloadMedia(mediaRef: string) {
try {
var storage = firebase.storage();
var pathReference = storage.ref(mediaRef);
const downloadUrl = await pathReference.getDownloadURL();
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = (event) => {
var blob = xhr.response;
};
xhr.open('GET', downloadUrl);
return downloadUrl;
} catch (e) {
switch (e.code) {
case 'storage/object-not-found':
console.warn('File does not exist.');
break;
case 'storage/unauthorized':
console.warn('Unauthorized.');
break;
case 'storage/canceled':
console.warn('Upload cancelled.');
break;
case 'storage/unknown':
console.warn('Unknown error.');
break;
}
}
}
However, I do not understand how to use the firebase library to download the file itself with the URL that it provides me.
Thanks.
Found a solution which doesn't involve me downloading the media but instead playing it directly with the download URL.
Using package 'expo-av'.
Hope this helps someone in my shoes!
export default function AudioPlay({ mediaDownloadUrl } : AudioPlayProps) {
const [sound, setSound] = React.useState<Audio.Sound | null>(null);
async function playSound() {
if (typeof mediaDownloadUrl !== 'string') return null;
try {
const { sound } = await Audio.Sound.createAsync(
{ uri: mediaDownloadUrl }
);
setSound(sound);
await sound.playAsync();
} catch (e) {
console.warn(e);
}
}
React.useEffect(() => {
return sound
? () => {
console.log('Unloading Sound');
sound.unloadAsync(); }
: undefined;
}, [sound]);
// ....

How to return error object in in a HTTP API Future request

I am using BLOC Pattern, so my query is how to return some error post HTTP request.
Suppose if the API returns 200 as a status code I can return the particular model which I have mentioned if there is an error returning from the API like 302, 404 401... so on so how to handle this and return UI to show the error message
Future<SampleModel> getSomeDetails(String ID) async {
var response =
await http.get(someURL,
headers: {'Content-type': 'application/x-www-form-urlencoded',});
if (response.statusCode == 200) {
return SampleModel.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');// return the error to UI
}
}
PS: I am also using the observer Pattern
You could return:
Future.error("Error message").
Then you could do something like this:
getSomeDetails("id")
.then((value) => print('Value: $value'))
.catchError((error) => print('Error: $error'));
or
FutureBuilder(
future: getSomeDetails("id"),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text('Value: ${snapshot.data}');
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
return Text('Loading...');
},
)
Because you are using bloc, you probably have some kind of stream that you add data to:
StreamController<int> data = new StreamController<int>();
And you probably use StreamBuilder to listen for events on that stream and show the data. You can also listen for the errors on the stream:
StreamBuilder<int>(
builder: (context, snapshot) {
if (snapshot.hasError) {
// Show error message
return Text('An error occured');
} else if (snapshot.hasData) {
// Show data
return Text('${snapshot.data}');
}
// No data, show loader
return CircularProgressIndicator();
},
stream: data.stream,
),
So you can just an error to the stream:
// Adding an error to the stream
data.addError('Failed to load post');
I am using my own API call mechanism Which is given below in that you can manage all type of exceptions.
api_handler.dart
import 'dart:async';
import 'dart:convert';
import 'package:connectivity/connectivity.dart';
import 'package:package_name/base/api/api_exception.dart';
import 'package:package_name/utils/app_constatns.dart';
import 'package:package_name/utils/log_utils.dart';
import 'package:package_name/utils/preference_utils.dart';
import 'package:package_name/utils/strings.dart';
import 'package:http/http.dart' as http;
class ApiHandler {
// next three lines makes this class a Singleton
static ApiHandler _instance = new ApiHandler.internal();
final JsonDecoder _decoder = new JsonDecoder();
ApiHandler.internal();
factory ApiHandler() => _instance;
Future<bool> isInternetConnected() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile ||
connectivityResult == ConnectivityResult.wifi) {
return true;
}
return false;
}
Future<dynamic> get(String url) async {
LogUtils.d("====URL GET Call: $url");
String token = PreferenceUtils.getString(AppConstants.LOGGED_IN);
// ignore: unrelated_type_equality_checks
var isConnected = await isInternetConnected();
if (isConnected != true) {
return Future.error(ApiException(Strings.internetNotConnected));
}
return http.get(url, headers: {"Authorization": "Bearer $token"}).then(
(http.Response response) {
final int statusCode = response.statusCode;
LogUtils.d("====response ${response.body.toString()}");
if (statusCode < 200 || statusCode >= 400 || json == null) {
throw new ApiException(jsonDecode(response.body)["message"]);
}
return _decoder.convert(response.body);
});
}
Future<dynamic> post(String url, {body, encoding}) async {
LogUtils.d("====URL POST Call: $url");
LogUtils.d("====body : $body");
String token = PreferenceUtils.getString(AppConstants.LOGGED_IN);
var isConnected = await isInternetConnected();
if (isConnected != true) {
return Future.error(ApiException(Strings.internetNotConnected));
}
return http.post(url,
body: json.encode(body),
headers: { 'Content-type': 'application/json',
'Accept': 'application/json',
"Authorization": "Bearer $token"},
encoding: encoding)
.then((http.Response response) {
final int statusCode = response.statusCode;
LogUtils.d("====responseBody ${response.body.toString()}");
LogUtils.d("====responseStatusCode ${response.statusCode}");
if (statusCode < 200 || statusCode >= 400 || json == null) {
throw new ApiException(jsonDecode(response.body)["message"]);
}
return _decoder.convert(response.body);
});
}
}
api_exception.dart
class ApiException implements Exception {
String errorMsg = "Server not respond";
ApiException(String error) {
this.errorMsg = error ?? "Server not respond";
}
}
api_manager.dart
import 'dart:convert';
import 'dart:io';
import 'package:flutter_my_recipes/utils/log_utils.dart';
import 'package:flutter_my_recipes/utils/preference_utils.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'api_handler.dart';
class ApiManager {
// next three lines makes this class a Singleton
static ApiManager _instance = new ApiManager.internal();
ApiManager.internal();
factory ApiManager() => _instance;
static ApiHandler _handler;
static void init() {
_handler = new ApiHandler();
}
static Future<LoginRes> loginApi(Map<String, dynamic> json) {
return _handler.post(UrlConstants.LOGIN_URL, body: json).then((res) {
return LoginRes.fromJson(res);
});
}
}
API call example :-
void loginApiCall(BuildContext context, LoginReq _signInReq) {
ApiManager.loginApi(_signInReq.toJson()).then((signInResponse) {
notifyListeners();
print("===Success $signInResponse");
PreferenceUtils.setString(
AppConstants.USERDATA, JsonCodec().encode(signInResponse.toJson()));
PreferenceUtils.setString(AppConstants.LOGGED_IN, signInResponse.token);
isLoading = false;
Navigation.pushAndRemoveUntil(context, Screens.HOME);
}).catchError((onError) {
isLoading = false;
notifyListeners();
print("===onError $onError");
ProcessDialog.closeLoadingDialog();
Toast.show(onError.errorMsg, context, duration: 2);
});
}
You have to call ApiManager init method in main.dart file so you can use Apimanager Instance allover the app.

Stream and Future in Dart

I've been using basic async/await for some time without many problems and I thought I understood how it worked. Can't say I'm an expert in it, but I understadn the gist of it. I just can't get my head around Streams though. Before today I thought I understood how they worked (basically ala Reactive Programming), but I can't get them to work in Dart.
I'm working on a persistance layer with the possibility of saving and retrieving (json) files. I've been using the fileManager example as a guideline.
import 'dart:io';
import 'dart:async';
import 'package:intl/intl.dart'; //date
import 'package:markdowneditor/model/note.dart';//Model
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:flutter/foundation.dart'; //log
import 'package:simple_permissions/simple_permissions.dart';//OS permissions
class FileManager {
static final FileManager _singleton = new FileManager._internal();
factory FileManager() {
return _singleton;
}
FileManager._internal();
Future<String> get _localPath async {
final directory = (await getApplicationDocumentsDirectory()).toString();
return p.join(directory, "notes"); //path takes strings and not Path objects
}
Future<File> writeNote(Note note) async {
var file = await _localPath;
file = p.join(
file,
DateFormat('kk:mm:ssEEEMMd').format(DateTime.now()) +
" " +
note.title); //add timestamp to title
// Write the file
SimplePermissions.requestPermission(Permission.WriteExternalStorage)
.then((value) {
if (value == PermissionStatus.authorized) {
return File(file).writeAsString('$note');
} else {
SimplePermissions.openSettings();
return null;
}
});
}
Future<List<Note>> getNotes() async {
//need file access permission on android. use https://pub.dartlang.org/packages/simple_permissions#-example-tab-
final file = await _localPath;
SimplePermissions.requestPermission(Permission.ReadExternalStorage)
.then((value) {
if (value == PermissionStatus.authorized) {
try {
Stream<FileSystemEntity> fileList =
Directory(file).list(recursive: false, followLinks: false);
// await for(FileSystemEntity s in fileList) { print(s); }
List<Note> array = [];
fileList.forEach((x) {
if (x is File) {
var res1 = ((x as File).readAsString()).then((value2) {
Note note = Note.fromJsonResponse(value2);
return note;
}).catchError((error) {
debugPrint('is not file content futurestring getNoteError: $x');
return null;
});
var array2 = res1.then((value3) {
array.add(value3);
return array;
});
//?
} else {
debugPrint('is not file getNoteError: $x');
}
});
// Add the file to the files array
//Return the Future<List<Note>>
return array;
} catch (e) {
debugPrint('getNoteError: $e');
// If encountering an error, return 0
return null;
}
} else {
SimplePermissions.openSettings();
return null;
}
});
}
}
Obviously as it is it won't work, but even trying to await the loop using the commented out parts raises an error.
In "getNotes", after checking the permissions I want to get an array of all the files in the directory, parse them as Note objects and return the resulting array.
I get the list of files:
Stream<FileSystemEntity> fileList =
Directory(file).list(recursive: false, followLinks: false);
And for each one of them in the stream I want to parse the file into an object and append it to an array to return at the end.
List<Note> array = [];
fileList.forEach((x) {
if (x is File) {
var res1 = ((x as File).readAsString()).then((value2) {
Note note = Note.fromJsonResponse(value2);
return note;
}).catchError((error) {
debugPrint('is not file content futurestring getNoteError: $x');
return null;
});
var array2 = res1.then((value3) {
array.add(value3);
return array;
});
//?
} else {
debugPrint('is not file getNoteError: $x');
}
});
// Add the file to the files array
//Return the Future<List<Note>>
return array;
Stream.forEach() returns a Future. Your last return statement runs immediately after the for-each call, but should await it.
await fileList.forEach((x) {
...
https://api.dartlang.org/stable/2.2.0/dart-async/Stream/forEach.html

Resources