Back

Question about class access for authentication (Flutter)

  • 0
  • Flutter
SoloTalent
9 Aug, 2023, 20:37

Hello everyone,

I have a question about an example I copied from here: https://github.com/saimon24/flutter-appwrite-auth.

I would like to access the same AuthAPI class in other classes, for example to get the UserId. What is the easiest way to do this without saving data?

Just started with Flutter and can't really find anything about it (maybe I'm just searching wrong).

Thanks! Greeting, Manuel

TL;DR
TL;DR: The user is having trouble with a Flutter app and accessing a class for authentication. They are using an example code and want to access the same class in other classes without saving data. There are suggestions to learn more about Flutter state management and to use `context.read<AuthAPI>()` to retrieve the user ID. They also encounter an error message related to accessing `context` in an initializer. Solution: Instead of accessing `context` in the initializer, retrieve the user ID with `final AuthAPI appwrite = context.read<AuthAPI>(); appwrite.userid`.
SoloTalent
9 Aug, 2023, 20:37

Question about class access for authentication (Flutter)

XaFigg
9 Aug, 2023, 20:39

Hello !

From the code, I'd say you can retrieve the existing AuthAPI instance with this line final AuthAPI appwrite = context.read<AuthAPI>();

XaFigg
9 Aug, 2023, 20:41

You can retrieve the user id with this code:

TypeScript
final AuthAPI appwrite = context.read<AuthAPI>();
appwrite.userid // <-- retrieve user id from AuthAPI instance
SoloTalent
9 Aug, 2023, 20:48

Hi, first of all, thank you for your quick reply. But if I try your solution in this code:

TypeScript
class EditProfilePage extends StatefulWidget {
  const EditProfilePage({Key? key}) : super(key: key);
  @override
  State<EditProfilePage> createState() => _EditProfilePageState();
}

class _EditProfilePageState extends State<EditProfilePage> {
  bool _isLoading = true;
  final AuthService authService = context.read<AuthService>();
  String userId = authService.currentUser.$id;
  UserProfile? user;
  UserService userService = UserService();
  @override
  void initState() {
    super.initState();
    _getData();
  }
  _getData() async {
    user = await userService.fetchCurrentUser(userId);
    _isLoading = false;
  }
@override
  Widget build(BuildContext context) {
.....```

The error message:
``The instance member 'context' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different``
is displayed
Drake
9 Aug, 2023, 20:53

It needs to go in initState

SoloTalent
9 Aug, 2023, 20:54

Ok so it has to look something like this?

TypeScript
class _EditProfilePageState extends State<EditProfilePage> {
  bool _isLoading = true;
  late AuthService authService;
  late String userId;
  late UserProfile user;

  UserService userService = UserService();

  @override
  void initState() {
    super.initState();
    authService = context.read<AuthService>();
    userId = authService.currentUser.$id;
  }

  _getData() async {
    user = await userService.fetchCurrentUser(userId);
    _isLoading = false;
  }```
Drake
9 Aug, 2023, 20:56

btw it's best to use 3 backticks for multiline code

Drake
9 Aug, 2023, 20:58

and you can also add dart after the first 3 backticks to get syntax highlighting 😉

SoloTalent
9 Aug, 2023, 21:03

@Steven thank you for your help. But I see the CircularProgressIndicator (only if _isLoading == true) the hole time although the data is arrived in the Service class 😮

Drake
9 Aug, 2023, 21:04

what's the rest of yoru code? what's the result of fetchCurrentUser()?

SoloTalent
9 Aug, 2023, 21:06

This is the Widget build:

TypeScript
@override
  Widget build(BuildContext context) {
    _getData();
    return Scaffold(
        drawer: SideNavDrawer(),
        appBar: buildAppBar(context, "Profil bearbeiten"),
        body: _isLoading
            ? const Center(
                child: CircularProgressIndicator(),
              )
            : ListView(
....```

The answer from ``fetchCurrentUser`` is the UserProfile entity.
SoloTalent
9 Aug, 2023, 21:07

The fetchCurrentUser function:

TypeScript
Future<UserProfile> fetchCurrentUser(String id) async {
    final docmentList = await db.listDocuments(
        databaseId: APPWRITE_DATABASE_ID,
        collectionId: COLLECTION_USER,
        queries: [Query.equal("user_id", id)]);
    print("Done");
    return docmentList.documents
        .map((e) => UserProfile.fromMap(e.data))
        .toList()[0];  
}```

And the ``print("Done")`` is very fast in the debug console.
Drake
9 Aug, 2023, 21:13

so the problem with this is there is nothing telling Flutter that _isLoading has been updated and that it needs to re-render.

I recommend finding some additional tutorials on flutter and state. both of the problems you raised are flutter topics and not appwrite specific

SoloTalent
9 Aug, 2023, 21:32

Thanks for your help 😉

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more