Categories
discuss

How should friend requests and invitations be handled in firebase, flutter? [closed]

I’m building an app using flutter and firebase. In this app I want the users to be able to invite each other to teams or add each other as friends. To do this, the user who wants to invite has to enter some information about the other user(s), preferably email.

One way of doing this that I thought of was to somehow get the UUID of the other user and add an invitation to a list in their user document in the database. I’m not sure about the security risks this brings though. I can’t find a way of getting a UUID from an email address and I don’t want the users to have to type in the UUID themselves.

Another way could be to send an invitation link via email. The link could be a dynamic link created by firebase. Though I would prefer to do everything in-app and not having to send emails.

What would be the best way of implementing this feature using firebase and flutter?

Answer

In order to achieve your goal, you can use Firebase dynamic links. A link to a tutorial you can find here: Intro

There are also some video tutorials explaining how to create and receive a dynamic link. The principle is simple. You create a link which you want to send to your friend inviting them to download your app. At the end of the link you attach the UUID of the sender. When the receiver opens it, you can reward both the sender’s UUID and the receiver’s UUID with some reward for sharing your app.

An advantage of using the dynamic link is that even if the receiver hasn’t downloaded your app yet, the link will first redirect the user to Google Play or AppStore depending on the phone and when he gets your app, the information of the link will be automatically received. In other word the receiver doesn’t need to click twice on the link. The information in your case will be the sender’s UUID. Then you can reward both users.

You can find a good tutorial for iOS also here:

Integrate Firebase Dynamic Links to iOS Apps

Categories
discuss

No FCM diagnostics when dialing *#*#426#*#*

I’m currently debugging issues where FCM push messages are sporadically not delivered to my Android app.
The principal setup and configuration works, most (high prio) push messages are delivered in a timely manner – but sometimes they are not.

When perusing the official troubleshoot guide (https://firebase.google.com/support/troubleshooter/fcm/delivery/diagnose/android), it advises me to dial *#*#426#*#* to get some diagnostics.

I’ve tried this now on three phones (Samsung Galaxy S7, Samsung XCover 4S, Motorola Moto X) but nothing happens – the phone just tries to do the call.

I’ve assumed that “dial this code” means “Open up the dialer app, enter this code, pick up”. Was that incorrect?

Answer

Ok, found it.

This only works with Android’s default dialer app or the Phone by Google app that can be loaded from the Play Store.
The custom dialers included by some handset makers (glaring at you Samsung) can’t do it.

So, to get the diagnostics: Make sure to use the right dialer.

Categories
discuss

MapboxGL JS – Display 3d buildings in lower zoom level

I use MapboxGL JS v2 with mapbox://styles/mapbox/streets-v11 style.
And I use this code to display 3D buildings on my map:

map.addLayer({
    'id': '3d-buildings',
    'source': 'composite',
    'source-layer': 'building',
    'filter': ['==', 'extrude', 'true'],
    'type': 'fill-extrusion',
    'minzoom': 15,
    'paint': {
        'fill-extrusion-color': '#666',
        'fill-extrusion-height': ['interpolate', ['linear'], ['zoom'], 15, 0, 15.05, ['get', 'height']],
        'fill-extrusion-base': ['interpolate', ['linear'], ['zoom'], 15, 0, 15.05, ['get', 'min_height']],
        'fill-extrusion-opacity': 0.9,
    }
});

It’s working as expected, as seen in this example.

Now, what I want is to load these buildings at lower zoom level, for example 10 instead of 15.
So, I changed minzoom from 15 to 10, and I also changed the interpolate stuff to use linear interpolation from 10 to 15.05.

Here is the final code:

map.addLayer({
    'id': '3d-buildings',
    'source': 'composite',
    'source-layer': 'building',
    'filter': ['==', 'extrude', 'true'],
    'type': 'fill-extrusion',
    'minzoom': 10,
    'paint': {
        'fill-extrusion-color': '#666',
        'fill-extrusion-height': ['interpolate', ['linear'], ['zoom'], 10, 0, 15.05, ['get', 'height']],
        'fill-extrusion-base': ['interpolate', ['linear'], ['zoom'], 10, 0, 15.05, ['get', 'min_height']],
        'fill-extrusion-opacity': 0.9,
    }
});

Unfortunately it’s not working, it looks like it still waits for zoom level 15 to load, and I didn’t find anything on the internet to make it work.

Answer

It seems like tile set’s for building are generated after zoom level 13.

READ HERE

So, when we query map queryRenderedFeatures({ layers: ["3d-buildings"] }); on zoom level below 13 no feature’s get added on Map. But once the zoom level is greater then 13 few building feature’s get added.

Screenshot zoom level<13

enter image description here

Screenshot zoom level>13

enter image description here

UPDATE

In order to make it work from zoom level 10 to 15, You have to create your own tileset using Tilesets CLI where you have to make a recipe json and have to provide zoom levels like:

{
   "version": 1,
   "layers": {
   "building_footprints": {
   "source": "mapbox://tileset-source/username/building-footprints",
   "minzoom": 10, //<---
   "maxzoom": 15
   }
 }
}

Screenshot: enter image description here

Step by Step Creation

Thanks!

Categories
discuss

Switch expression with void return type

Is there any way to force an exhaustive check of all enum values when the switch branches call methods with void return type? It’s quite ugly to hard-code a yield just to coax the compiler to demand exhaustiveness.

This is my current pattern (the handle methods have void return type)

int unused = switch (event.getEventType()) {
    case ORDER   -> { handle((OrderEvent) event); yield 0; }
    case INVOICE -> { handle((InvoiceEvent) event); yield 0; }
    case PAYMENT -> { handle((PaymentEvent) event); yield 0; }
};

The reason I want to use an expression is to get a compilation error when a new enum value is added and is not handled.

Answer

Maybe yield a Consumer of Event, so you yield something useful, the trade off is one more line for consumer.accept.

Consumer<Event> consumer = switch (event.getEventType()) {
    case ORDER -> e -> handle((OrderEvent) e);
    case INVOICE -> e -> handle((InvoiceEvent) e);
    case PAYMENT -> e -> handle((PaymentEvent) e);
};
consumer.accept(event);

Continue if you concern performance

Based on the comment concerning performance penalty, a benchmark is performed to compare following scenarios:

  1. Using consumer and handle is instance method
  2. Using consumer and handle is static method
  3. Not using consumer and handle is instance method
  4. Not using consumer and handle is static method

To see

  • Is using Consumer has large performance impact?
  • Is there any difference for static and instance handle method?

And the result is:

# Run complete. Total time: 00:20:30

Benchmark                                          Mode  Cnt      Score     Error   Units
SwitchExpressionBenchMark.consumerHandle          thrpt  300  49343.496 ±  91.324  ops/ms
SwitchExpressionBenchMark.consumerStaticHandle    thrpt  300  49312.273 ± 112.630  ops/ms
SwitchExpressionBenchMark.noConsumerHandle        thrpt  300  49353.232 ± 106.522  ops/ms
SwitchExpressionBenchMark.noConsumerStaticHandle  thrpt  300  49496.614 ± 122.916  ops/ms

By observing the result, there is no much different between the 4 scenarios.

  • Using Consumer does not have significant performance impact.
  • The performance different between static and instance handle method is neglectable.

The benchmark is performed with:
CPU: Intel(R) Core(TM) i7-8750H
Memory: 16G
JMH version: 1.19
VM version: JDK 15.0.2

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
@Warmup(iterations = 30, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 30, time = 500, timeUnit = TimeUnit.MILLISECONDS)
public class SwitchExpressionBenchMark {
    public static void main(String[] args) throws Exception {
        org.openjdk.jmh.Main.main(args);
    }

    @Benchmark
    public void consumerStaticHandle(Blackhole blackhole, InvoiceEvent invoiceEvent) {
        Event event = invoiceEvent;
        Consumer<Event> consumer = switch (event.getEventType()) {
            case ORDER -> e -> staticHandle((OrderEvent) e);
            case INVOICE -> e -> staticHandle((InvoiceEvent) e);
            case PAYMENT -> e -> staticHandle((PaymentEvent) e);
        };
        consumer.accept(event);
    }

    @Benchmark
    public void consumerHandle(Blackhole blackhole, InvoiceEvent invoiceEvent) {
        Event event = invoiceEvent;
        Consumer<Event> consumer = switch (event.getEventType()) {
            case ORDER -> e -> this.handle((OrderEvent) e);
            case INVOICE -> e -> this.handle((InvoiceEvent) e);
            case PAYMENT -> e -> this.handle((PaymentEvent) e);
        };
        consumer.accept(event);
    }

    @Benchmark
    public void noConsumerHandle(Blackhole blackhole, InvoiceEvent invoiceEvent) {
        Event event = invoiceEvent;
        int unused = switch (event.getEventType()) {
            case ORDER -> {
                this.handle((OrderEvent) event);
                yield 0;
            }
            case INVOICE -> {
                this.handle((InvoiceEvent) event);
                yield 0;
            }
            case PAYMENT -> {
                this.handle((PaymentEvent) event);
                yield 0;
            }
        };
    }

    @Benchmark
    public void noConsumerStaticHandle(Blackhole blackhole, InvoiceEvent invoiceEvent) {
        Event event = invoiceEvent;
        int unused = switch (event.getEventType()) {
            case ORDER -> {
                staticHandle((OrderEvent) event);
                yield 0;
            }
            case INVOICE -> {
                staticHandle((InvoiceEvent) event);
                yield 0;
            }
            case PAYMENT -> {
                staticHandle((PaymentEvent) event);
                yield 0;
            }
        };
    }

    private static void staticHandle(PaymentEvent event) {
        doSomeJob();
    }

    private static void staticHandle(InvoiceEvent event) {
        doSomeJob();
    }

    private static void staticHandle(OrderEvent event) {
        doSomeJob();
    }

    private void handle(PaymentEvent event) {
        doSomeJob();
    }

    private void handle(InvoiceEvent event) {
        doSomeJob();
    }

    private void handle(OrderEvent event) {
        doSomeJob();
    }

    private static void doSomeJob() {
        Blackhole.consumeCPU(16);
    }

    private enum EventType {
        ORDER, INVOICE, PAYMENT
    }

    public static class Event {
        public EventType getEventType() {
            return eventType;
        }

        public void setEventType(EventType eventType) {
            this.eventType = eventType;
        }

        private EventType eventType;

        public double getD() {
            return d;
        }

        public void setD(double d) {
            this.d = d;
        }


        private double d;
    }

    public static class OrderEvent extends Event {
    }

    @State(Scope.Thread)
    public static class InvoiceEvent extends Event {
        @Setup(Level.Trial)
        public void doSetup() {
            this.setEventType(EventType.INVOICE);
        }
    }

    public static class PaymentEvent extends Event {
    }
}
Categories
discuss

How to access iOS UserDefaults stored data in Flutter SharedPrefrences

I have an iOS app already on Store, Now planning to replace it with Flutter with new version release.

I want to get access native app’s UserDefaults data in Flutter code.

Using the way suggested in Flutter docs I m getting null value. What I have tried is:

In my pubspec.yaml file :

dependencies:
  shared_preferences: ^0.5.12+4

Im my home.dart class file I’m importing header :

import 'package:shared_preferences/shared_preferences.dart';

And this is how I m trying to access data stored in iOS app from native app, I m using same bundle ID (Package ID) in flutter project to overwrite the app and it is successfully overwriting.

@override
void initState() {
    super.initState();
    getFromLocalMemory('user').then((value) =>
      userInfo = value
  );
}



Future<String> getFromLocalMemory(String key) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String user = prefs.getString(key);
    return user;
}

It always returns null. While ‘user’ key has data when getting from iOS native app.

Answer

In that case, I suggest you use platform channel method

platform channels

iOS doesn’t seem to allow flutter framework to access NSUserDefaults, when it didn’t create it from the beginning,..

I hope it will work for you.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..