Migrating rxdart from 0.18 to 0.24 - redux

I've upgraded to the most recent version of flutter and I've started going through now and upgrading the packages I use as well. I've noticed there are some breaking changes that have happened in several packages, but the breaking changes in the rxdart package have got me stumped.
the developers have kept up their changelogs and mentioned in 0.23.0 they removed the observable class as seen here and they even made a codemod package to try to make the migration easy, which can be seen here. this repaired only a couple of my issues, and left several more.
Epic<AppState> getConversationPreviewsEpic(ConversationRepository repo) {
return (Stream<dynamic> actions, EpicStore<AppState> store) {
return Stream(actions)
.whereType<SubscribeConversationPreviews>() // <-- subscribe to conversations stream
.where((action) => action.fromUser != null)
.switchMap((action) {
isConversationLoading = true;
return repo
.getConversationPreviewStream(action.fromUser, lastSnapshotAction: (lastTimeStamp, hasMore){
lastConversationTimeStamp = lastTimeStamp;
hasMoreConversations = hasMore;
})
.map((rooms) => ConversationPreviewsSnapshot(rooms)) //<-- when new conversations come in add them to the redux store
.takeUntil(actions.where((a) => a is UnsubscribeConversationPreviews)); //<-- unsubscribe from conversations stream
});
};
}
all of the issues I have are similar to this one here. I wish I could underline stuff in red like my editor does here. So on line 2 of the code block where it says
Stream<dynamic> actions
I get an error that Stream isn't a type
and then on the next line
return Stream(actions)
I get an error that Stream() doesn't take any arguments. I take away the arguments and the redline goes away but I can't test to see if the code still works because I can't figure out how to fix the first error.
One last thing, fromIterable and fromFuture don't work anymore and I don't see in the documentation how to adjust them to make them work again

RxDart 0.24.x based on extension method, call methods on Stream directly.
import 'package:rxdart/rxdart.dart';
actions.whereType< SubscribeConversationPreviews >();

Related

How do I return the custom metaData from firebase storage, using the admin.storage() method

so I am trying to add image moderation to my firebase app, using this guide here here is the repo and this also might be useful. I tested it out and it seems to work well, however I wanted to update the same image from storage, not upload it to a separate path. This caused the firebase function to fire recursively and I cost my company a couple of dollars. To solve this I decided whenever an image is uploaded there would be custom metadata saying if it has been blurred or not. The code for this is down below and works.
const metaData = {
customMetadata: {
blurred: 'false',
},
}
const imageBytes = await uploadBytesResumable(storageRef, blobFile, metaData);
Now in my firebase function every time an image is uploaded it will check the object.metaData to see if it is equal to 'true'. Here is the code down below for that.
export const blurOffensiveImages = functions.storage.object().onFinalize(async (object) => {
// Ignore things we've already blurred
if (object.metadata?.customMetadata.blurred === 'true') {
functions.logger.log(`meta datas are the same, stopping function`);
return null;
}
If the metadata is equal to false then it will run the normal function and check if the image is worth blurring. If it is then all it does is change the metadata to true since this will stop the recursion.
My problem, I am having type errors saying 'Property "blurred' does not exist on type 'string'". I have played around with this for a while and cant seem to find a solution to get the customMetaData to come out the way I would like. If i remove the .blurred I get no errors but I also know this would not give the correct data when I check if it is equal to 'true'or 'false'. If anyone knows how to fix this that would be really appreciated. OR if someone has a good solution to stop this recurson from happening that would also be great since this has been giving me issues for a few days. Thanks!

Firebase & Flutter (on Android) - MessagingToken is null

I'm running into trouble with some of my app's subscribers. We recently introduced the ability to send out notifications to our users using FirebaseMessaging. I should also mention that the app is on Android only.
Here is a brief section of code that we are running
updateUser(Userx user) async {
var messagingToken = await FirebaseMessaging.instance.getToken();
var packageInfo = await PackageInfo.fromPlatform();
user.messagingToken = messagingToken!;
user.appVersion = packageInfo.version;
await Users.updateUser(user);
}
It turns out that the FirebaseMessaging.instance.getToken() sometimes returns null and I can't figure out why that would be the case. The documentation also doesn't say much.
Could this be device specific? Maybe a user-setting to not allow any in-app messages?
A potential workaround is of course to null-check the token and simply accept it being null but I would like to understand the reasons behind that.
I found one more method that could be helpful, but I'm unsure about it.
Call FirebaseMessaging.instance.isSupported() first and act based on the result.

Firestore is unusably slow with a simple hello world scenario

I have one collection with a document that has a subcollection of three documents something like this.
task-sets: {
"<owners-uid>": {
owner: <owners-uid>,
tasks: {
"<task 1 id>": {
name: 'Bake a Cake',
description: 'Bake a delicious cake with a colorful frosting.'
},
"<task 2 id>": {
name: 'Invite Friends',
description: 'Invite any friends that might enjoy delicious cake.'
},
"<task 3 id>": {
name: 'Pin Tail on Donkey',
description: 'Blindfold a guest and have them attempt to pin a paper tail to a poster of a tailless donkey.'
},
}
}
I then run this code to get this one document.
export async function getRemoteTasks() {
const user = authState.get().user;
const db = firebase.firestore();
console.time('getRemoteTasks');
const taskSetDocument = await db.collection('task-sets').doc(user.uid).get();
const querySnapshot = await taskSetDocument.ref.collection('tasks').get();
console.timeEnd('getRemoteTasks');
let tasks = [];
querySnapshot.forEach(fillArray(tasks));
return tasks;
}
The two query lines in this function between console.time and console.timeEnd take 115 seconds to run.
Please do not duplicate this. Believe me, I've gone through every single one of the slow firestore query questions on SO. All of them are performance problems. My problem is that firestore is broken for me. This is a simple hello world test case with a relatively simple query. It is taking forever. Something is broken here. I need to know what that is. None of the other questions answered my problem at all.
Maybe its because this is a development run and if I deployed it, it would get faster. Please, I've put so much work into this project as a firebase project, and this one problem is a deal breaker for me.
Eureka! I found my problem and the solution. It was very esoteric. I have a react app. I am using a package called react-ridge-state to hold globally the authentication status of my user. I have an Authentication provider that sets that global state. What I didn't realize is that react-ridge-state causes a component rerender when the state is changed. I suppose that is the point of it. This created an infinite loop rerender. That was causing the slow down, probably because it wasn't letting the promise resolve.
I wish there was a way to increase the visibility of rerender loops like this. This solution came to me in a dream last night, and I put a breakpoint in my code and found the loop. Way to go intuition!
Solution: Continuous rendering of components was preventing resolution of the promise returned by firestore.

Meteor: send message to user at hot code push

How can I let the user know when they are getting a hot code push?
At the moment the screen will go blank during the push, and the user will feel it's rather weird. I want to reassure them the app is updating.
Is there a hook or something which I can use?
Here's the shortest solution I've found so far that doesn't require external packages:
var ALERT_DELAY = 3000;
var needToShowAlert = true;
Reload._onMigrate(function (retry) {
if (needToShowAlert) {
console.log('going to reload in 3 seconds...');
needToShowAlert = false;
_.delay(retry, ALERT_DELAY);
return [false];
} else {
return [true];
}
});
You can just copy that into the client code of your app and change two things:
Replace the console.log with an alert modal or something informing the user that the screen is about to reload.
Replace ALERT_DELAY with some number of milliseconds that you think are appropriate for the user to read the modal from (1).
Other notes
I'd recommend watching this video on Evented Mind, which explains what's going on in a little more detail.
You can also read the comments in the reload source for further enlightenment.
I can image more complex reload logic, especially around deciding when to allow a reload. Also see this pacakge for one possible implementation.
You could send something on Meteor.startup() in your client-side code. I personally use Bert to toast messages.

Firebase and Angularfire nightmare migration for Update

I am new to firebase and I am having a bit of a nightmare trying to adapt old code to what is now deprecated and what is not. I am trying to write a function which updates one "single" record in my datasource using the now approved $save()promise but it is doing some really strange stuff to my data source.
My function (should) enables you to modify a single record then update the posts json array. However, instead of doing this, it deletes the whole datasource on the firebase server and it is lucky that I am only working with testdata at this point because everything would be gone.
$scope.update = function() {
var fb = new Firebase("https://mysource.firebaseio.com/Articles/" + $scope.postToUpdate.$id);
var article = $firebaseObject(ref);
article.$save({
Title: $scope.postToUpdate.Title,
Body: $scope.postToUpdate.Body
}).then(function(ref) {
$('#editModal').modal('hide');
console.log($scope.postToUpdate);
}, function(error) {
console.log("Error:", error);
});
}
Funnily enough I then get a warning in the console "after" I click the button:
Storing data using array indices in Firebase can result in unexpected behavior. See https://www.firebase.com/docs/web/guide/understanding-data.html#section-arrays-in-firebase for more information. Also note that you probably wanted $firebaseArray and not $firebaseObject.
(No shit?) I am assuming here that $save() is not the right call, so what is the equivalent of $routeParams/$firebase $update()to do a simple binding of the modified data and my source? I have been spending hours on this and really don't know what is the right solution.
Unless there's additional code that you've left out, your article $firebaseObject should most likely use the fb variable you created just before it.
var article = $firebaseObject(fb);
Additionally, the way in which you're using $save() is incorrect. You need to modify the properties on the $firebaseObject directly and then call $save() with no arguments. See the docs for more.
article.Title = $scope.postToUpdate.Title;
article.Body = $scope.postToUpdate.Body;
article.$save().then(...

Resources