Giter Club home page Giter Club logo

dart-sdk's Introduction

PocketBase - open source backend in 1 file

build Latest releases Go package documentation

PocketBase is an open source Go backend, consisting of:

  • embedded database (SQLite) with realtime subscriptions
  • built-in files and users management
  • convenient Admin dashboard UI
  • and simple REST-ish API

For documentation and examples, please visit https://pocketbase.io/docs.

Warning

Please keep in mind that PocketBase is still under active development and therefore full backward compatibility is not guaranteed before reaching v1.0.0.

API SDK clients

The easiest way to interact with the API is to use one of the official SDK clients:

Overview

Use as standalone app

You could download the prebuilt executable for your platform from the Releases page. Once downloaded, extract the archive and run ./pocketbase serve in the extracted directory.

The prebuilt executables are based on the examples/base/main.go file and comes with the JS VM plugin enabled by default which allows to extend PocketBase with JavaScript (for more details please refer to Extend with JavaScript).

Use as a Go framework/toolkit

PocketBase is distributed as a regular Go library package which allows you to build your own custom app specific business logic and still have a single portable executable at the end.

Here is a minimal example:

  1. Install Go 1.21+ (if you haven't already)

  2. Create a new project directory with the following main.go file inside it:

    package main
    
    import (
        "log"
        "net/http"
    
        "github.com/labstack/echo/v5"
        "github.com/pocketbase/pocketbase"
        "github.com/pocketbase/pocketbase/apis"
        "github.com/pocketbase/pocketbase/core"
    )
    
    func main() {
        app := pocketbase.New()
    
        app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
            // add new "GET /hello" route to the app router (echo)
            e.Router.AddRoute(echo.Route{
                Method: http.MethodGet,
                Path:   "/hello",
                Handler: func(c echo.Context) error {
                    return c.String(200, "Hello world!")
                },
                Middlewares: []echo.MiddlewareFunc{
                    apis.ActivityLogger(app),
                },
            })
    
            return nil
        })
    
        if err := app.Start(); err != nil {
            log.Fatal(err)
        }
    }
  3. To init the dependencies, run go mod init myapp && go mod tidy.

  4. To start the application, run go run main.go serve.

  5. To build a statically linked executable, you can run CGO_ENABLED=0 go build and then start the created executable with ./myapp serve.

Note

PocketBase embeds SQLite, but doesn't require CGO.

If CGO is enabled (aka. CGO_ENABLED=1), it will use mattn/go-sqlite3 driver, otherwise - modernc.org/sqlite. Enable CGO only if you really need to squeeze the read/write query performance at the expense of complicating cross compilation.

For more details please refer to Extend with Go.

Building and running the repo main.go example

To build the minimal standalone executable, like the prebuilt ones in the releases page, you can simply run go build inside the examples/base directory:

  1. Install Go 1.21+ (if you haven't already)
  2. Clone/download the repo
  3. Navigate to examples/base
  4. Run GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build (https://go.dev/doc/install/source#environment)
  5. Start the created executable by running ./base serve.

Note that the supported build targets by the pure Go SQLite driver at the moment are:

darwin  amd64
darwin  arm64
freebsd amd64
freebsd arm64
linux   386
linux   amd64
linux   arm
linux   arm64
linux   ppc64le
linux   riscv64
linux   s390x
windows amd64
windows arm64

Testing

PocketBase comes with mixed bag of unit and integration tests. To run them, use the standard go test command:

go test ./...

Check also the Testing guide to learn how to write your own custom application tests.

Security

If you discover a security vulnerability within PocketBase, please send an e-mail to support at pocketbase.io.

All reports will be promptly addressed, and you'll be credited accordingly.

Contributing

PocketBase is free and open source project licensed under the MIT License. You are free to do whatever you want with it, even offering it as a paid service.

You could help continuing its development by:

PRs for new OAuth2 providers, bug fixes, code optimizations and documentation improvements are more than welcome.

But please refrain creating PRs for new features without previously discussing the implementation details. PocketBase has a roadmap and I try to work on issues in specific order and such PRs often come in out of nowhere and skew all initial planning with tedious back-and-forth communication.

Don't get upset if I close your PR, even if it is well executed and tested. This doesn't mean that it will never be merged. Later we can always refer to it and/or take pieces of your implementation when the time comes to work on the issue (don't worry you'll be credited in the release notes).

dart-sdk's People

Contributors

ganigeorgiev avatar irmhonde avatar rifaldhiaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dart-sdk's Issues

missed argument collection name inside buildUrl()

Hi first of all my overhaul experience with pocketbase its really great!!

Second I was workin with the function to get files from pocketbase with flutter and I realize something, in the documentation says that to get a file form a record you need to make another petition that return you a URI but I need to pass the next required arguments:

  • RECORD MODEL
  • FILENAME

the problem its with record model because in the file_service.dart of the sdk the function "buildUrl" need 3 arguments

  • collectionId form the record model
  • filename
  • recordId form the record model

but in the docs says:
Each uploaded file could be accessed by requesting its file url:
http://127.0.0.1:8090/api/files/COLLECTION_ID_OR_NAME/RECORD_ID/FILENAME

if I want to use the collection name it worn work because only expect the collection id argument or maybe I miss something reading the docs.

Question: pb.authStore.clear(); clears the auth store (token = '' and isValid = false), so why are api requests still successful?

iOS and Android, pocketbase: ^0.6.0

I logout with 'pb.authStore.clear();', but subsequent api requests still complete successfully. I would expect them to fail.
Now I have to check each api request with 'if (auth.isValid)'.
Doesn't seem quite right.
Wouldn't the api request(s) see the auth token is now '' and immediately fail (or at least update the headers it sends with the invalid token)?

Empty/non-set relations should not return as empty string in the result Json

When a record with a Relation field (e.g. named "relation") has no relation set, the resulting Json returns an empty string:

{
    "id": "2euaei6s2bs9kfx",
    "created": "2022-11-16 21:36:26.035Z",
    "updated": "2022-11-16 21:36:26.035Z",
    "collectionId": "wx8ugpt1m8dk2o5",
    "collectionName": "items",
    "expand": {},
    "name": "Some record name",
    "relation": ""
}

This is a problem when working with freezed and a model Item that expects a model Relation for the "relation" field.

@freezed
class Item with _$Item {
  const factory Item({
    String? id,
    required String name,
    Relation? relation,
  }) = _Item;

  factory Item.fromJson(Map<String, Object?> json) => _$ItemFromJson(json);
}

A null value would be more appropriate and not pose a problem when working with freezed.

Side note: Before that works, I additionally need to copy the full record data from the expand['relation'] field to relation since the latter would only contain ids, which would neither satisfy the Relation model. So I am questioning whether it makes sense to replace the (list of) id(s) in a relational field when expand=relation is given with the actual data set:

So instead of this (some default field omitted for brevity):

{
    "id": "bvo49tlzn8na3r6",
    "collectionName": "items",
    "expand": {
        "relation": {
            "id": "a74xecr0dl0mgh8",
            "collectionName": "relations",
            "expand": {},
            "name": "A relational record"
        }
    },
    "name": "An Item",
    "relation": "a74xecr0dl0mgh8"
}

have this instead

{
    "id": "bvo49tlzn8na3r6",
    "collectionName": "items",
    "name": "An Item",
    "relation": {
            "id": "a74xecr0dl0mgh8",
            "collectionName": "relations",
            "expand": {},
            "name": "A relational record"
        }
}

Weird format issue

Going through the Dart client

isAbort: false, statusCode: 500, response: {}, originalError: FormatException: Unexpected character (at character 1)
flutter: <!DOCTYPE html>
flutter: ^
flutter: }

Fetching via HTTP

 200 {"page":1,"perPage":30,"totalItems":6098,"totalPages":204,"items":

I am omitting the data from the response in the snippet. But After logging in with the client and making sure the auth store is valid the client still returns a 500 error.

Upgrade http to 1.0.0

As http version 1.0.0 is released I want to upgrade it in my project. The dependency of pocketbase sadly blocks this.
This could be done as a part of #41.

Issue with filtering in dart-sdk

Currently trying to search my collection of users using the "username" as the filter.
This is my method call:
pb.collection("users").getFullList(filter: 'username=$value')

This leads to a stacktrace that shows the url encoding for the filter call:
ClientException: {url: https://randompocket.io/api/collections/users/records?page=1&perPage=200&filter=username%3Dfriendly, isAbort: false, statusCode: 400, response: {code: 400, message: Invalid filter parameters., data: {}}, originalError: null}

If this is expected behavior, can you possibly add a gist showing how I should pass filters into this method? Thank you in advance.

Bug: authStore did not save token and model.

authStore did not save token, model on device persistent storage.

final auth = await pb.collection('users').authWithPassword('test_username', '12345678');
print(pb.authStore.token);
print(pb.authStore.isValid);
print(pb.authStore.model);

Result

I/flutter (18317):
I/flutter (18317): false
I/flutter (18317): null

I try to manually save the token and model result are same.

final auth = await pb.collection('users').authWithPassword('test_username', '12345678');
pb.authStore.save(auth.token, auth.record);
print(pb.authStore.token);
print(pb.authStore.isValid);
print(pb.authStore.model);

Result

I/flutter (18317):
I/flutter (18317): false
I/flutter (18317): null

I think it would be better if getFileUrl were placed in RecordModel.

So let’s say I have an internal model with an imageUrl in it.
That look like this:

class Post {
  Post({
    required this.text,
    required this.imageUrl,
  });
  
  static Post fromRecordModel(RecordModel model, PocketBase base){
    final text = model.getStringValue('text');
    final imageName = model.getStringValue('imageUrl'); // it returns only the name
    final imageUrl = base.getFileUrl(imageName, model);
    return Post(text: text, imageUrl: imageUrl);
  }
  
  final String text;
  final Uri imageUrl;
}

it has a fromRecordModel constructor. The only way to do it now is to pass pocketBase as an argument. But this feels wrong.

Wouldn’t it be better if I could call getFileUrl directly from the model something like this:

static Post fromRecordModel(RecordModel model){
    final text = model.getStringValue('text');
    final imageName = model.getStringValue('imageUrl'); // it returns only the name
    final imageUrl = model.getFileUrl(imageName);
    return Post(text: text, imageUrl: imageUrl);
  }

I tried to implement it by myself but it seems to be an issue with baseUrl, its accessible only in pocketBase instance.
This is what I thought about (but it doesn’t feel right).
First, I tried to pass the baseUrl into responseData but then I realized that someone could use a field named baseUrl, and by using it to pass baseUrl will override it.
Then I add it as an argument to RecordModel.fromJson(json, baseUrl) method, and this also feels wrong.
So the last idea is to have a singleton in which I will write baseUrl when PocketBase is initiated. And then I thought why would not we add a singleton for the entire PocketBase class as I saw in other packages? My question is how would be better?

can't reach the server from flutter when running in real android device

i wanted to access a collections which are in pocketbase server, it will work from postman using localhost,

but when I try to access it from dart code using my actual Android device, it will end up with Connection Timeout exception.

I tied:

  1. my PC and my android devices are on the same network.
  2. tried to change the ip to my real ip on my PC.

should I deploy to access it???

Unable to use realtime in flutter web

When trying to use the realtime feature in flutter I see in the logs two requests:

A GET request from guest to /api/realtime which responds with 200. I guess that's the subscription.

A POST request from user to /api/realtime which fails with 404 and meta:

{
  "errorDetails": "No client associated with connection ID \"2KJAld0HGCUSgANm7FtkEMavWlbpoVGFdXGrwOnh\"",
  "errorMessage": "Missing or invalid client id."
}

I guess that's the data I changed on the admin panel.

I use email auth and the user has credentials. The user is able to fetch from this collection. The code in flutter used is:

client.realtime.subscribe('demo', (e) {
    print(e.record);
});

Why is the first call as guest? Is this the reason why the second request fails?

Supporting auth through app cycles

I couldn't find a way to keep the authenticated state, through app cycles (closening/reopening the app), when authenticated through OAuth.
Does the SDK support this, or how would i go about this?

Parse expanded objects recursively into RecordModel

Currently when calling client.records.getFullList('collection', query: {'expand': 'relation1.relation2.relation3.'}); the result is a RecordModel but objects nested in expand are of type Map. Changing the nested objects into RecordModel (recursively) would make it easier to work with the expand option.

image

make models `RecordModel|AdminModel|null` use a base type `BaseModel` to avoid use of `dynamic`

There are 6 occurrences of the "union" RecordModel|AdminModel in the pockebase/dart-sdk:

Since dart does not have true unions I propose we implement some abstract parent type or with some mixin to provide "better than dynamic" types for locations in order to provide a better developer experience.

how to yield from subscription function

image

I am using riverpod with StreamProvider and want to use yield when new record created but I cant do that because RecordSubscriptionEven output Void at the end

Username/Password authentication from Flutter Web

pocketbase 0.18.5 (linux arm64)
Flutter (Channel stable, 3.13.4, on macOS 13.5.2 22G91 darwin-arm64, locale en-GB)

Trying to login with username/password now produces this exception:
"Expected a value of type 'Iterator', but got one of type 'DomIterator'"

pocketbase version and Flutter version both changed the same day. Was working before the updates (and still works from Android/iOS/Macos).
Any thoughts?

Need to Start Pocketbase Server from Dart

We are about to develop an offline first then save backup of data.db at server application.

we want to include pocketbase server in our app.

How we can start/serve pocketbase server from dart code

Persist auth between sessions

I was wondering if the SDK support persisting authentication between app restarts. upon restart, pb.authStore.isValid returns false. I couldn't find any documentation around this. Thanks :)

Realtime to non avail in Flutter

I cannot get realtime to work neither w/ pocketbase 0.7.10 and the Dart SDK 0.4.1 nor 0.8.0-rc2 and SDK version 0.5.0-rc2.

This is my test app for pocketbase 0.7.10 and the Dart SDK 0.4.1. I created a collection items and and a user with the given credentials. The pocketbase debug log shows "Realtime connection established …" but any change in the items collections would trigger the passed function in subscribe.

import 'package:flutter/material.dart';
import 'package:pocketbase/pocketbase.dart';

void main() {
  runApp(MainApp());
}

class MainApp extends StatelessWidget {
  MainApp({super.key});

  final client = PocketBase('http://127.0.0.1:8090');

  @override
  Widget build(BuildContext context) {
    void signIn() async {
      final userData = await client.users
          .authViaEmail('[email protected]', '1234567890');

      // Successfully establishes a connection, debug output is "Realtime connection established: bNuGMnn9Pmsdh9gCnkIWxnFRrL8JvYCS92ccWJLL"
      client.realtime.subscribe("items", (e) {
        // updating, inserting, deleting does not fire this function here
        print("Changed main $e");
      });
    }

    return MaterialApp(
      home: Center(
        child: ElevatedButton(
          onPressed: signIn,
          child: const Text("Realtime"),
        ),
      ),
    );
  }
}

The network shows a single GET call to /api/realtime whereas a sample React app I tested, and which works fine with realtime, additionally POSTs subscriptions etc.

Can someone post a minimal Flutter with working realtime subscriptions?

android app auth data

How to load recent authorization data after android app restarted and check if authorization is valid?

Flutter pocketbase db 501 error

Hi
Pocketbase is not working as intended with flutter and the error I'm getting has a status code of 501. Sometimes it connects and sometimes it doesn't I don't know what's wrong with the package

Need info

I am new to pb i just want to know that. Does pb dart sdk save auth data in browser on flutter web or should i have to save using other db like hive flutter

Migrating Database Collections from dart

We have been using the package: drift https://drift.simonbinder.eu/,
drift has a great feature of Migrating Database from the Client Side,
here is a guide to migration:
https://drift.simonbinder.eu/docs/advanced-features/migrations/

We need to get the current version of the database and then do some migration by dart code:

  • Adding a Column to a collection
  • Removing a Column from a collection
  • Changing collection name
  • Renaming a Column

We need the above feature because of the following reasons:

  1. Our app will be used offline first and then back up its database to the cloud.
  2. Our app will be installed on the user's device, so when we bring a new feature a column may add or remove automatically by opening their database.

Waiting for a guide on how to do Migration from the dart side.

How to filter the expanded items only

Hello,

I'm currently having an issue trying to filter out the expanded items to a certain condition, as as shown below:

final data = await pb.collection('categories').getList(expand: 'localization');

The resulted data would be like this:

{
  "page": 1,
  "perPage": 30,
  "totalItems": 1,
  "totalPages": 1,
  "items": [
    {
      "id": "tlcxv2utfpwj1fj",
      "created": "2023-09-15 20:08:53.062Z",
      "updated": "2023-09-15 20:08:53.062Z",
      "collectionId": "2rfgsuc64fouiv1",
      "collectionName": "categories",
      "expand": {
        "localization": [
          {
            "id": "2jlv6efy9s3f5l9",
            "created": "2023-09-15 20:08:34.425Z",
            "updated": "2023-09-15 21:53:48.724Z",
            "collectionId": "bv3sssp0ule357t",
            "collectionName": "categoriesLocalization",
            "expand": {},
            "locale": "ar",
            "subtitle": "تسلا ومرسيديس",
            "title": "سيارات"
          },
          {
            "id": "2ihfygz9uk8ac4d",
            "created": "2023-09-15 20:08:20.141Z",
            "updated": "2023-09-15 21:53:58.972Z",
            "collectionId": "bv3sssp0ule357t",
            "collectionName": "categoriesLocalization",
            "expand": {},
            "locale": "en",
            "subtitle": "Tesla and Mercedes",
            "title": "Cars"
          }
        ]
      },
      "image": "devmuaz_4_square_dPHZafvg8Q.jpg",
      "localization": [
        "2jlv6efy9s3f5l9",
        "2ihfygz9uk8ac4d"
      ]
    }
  ]
}

What I need is a way to filter the expand.localization to be equal to lets say ar only which also minimizes the response size. It would be something like this:

{
  "page": 1,
  "perPage": 30,
  "totalItems": 1,
  "totalPages": 1,
  "items": [
    {
      "id": "tlcxv2utfpwj1fj",
      "created": "2023-09-15 20:08:53.062Z",
      "updated": "2023-09-15 20:08:53.062Z",
      "collectionId": "2rfgsuc64fouiv1",
      "collectionName": "categories",
      "expand": {
        "localization": [
          {
            "id": "2jlv6efy9s3f5l9",
            "created": "2023-09-15 20:08:34.425Z",
            "updated": "2023-09-15 21:53:48.724Z",
            "collectionId": "bv3sssp0ule357t",
            "collectionName": "categoriesLocalization",
            "expand": {},
            "locale": "ar",
            "subtitle": "تسلا ومرسيديس",
            "title": "سيارات"
          }
        ]
      },
      "image": "devmuaz_4_square_dPHZafvg8Q.jpg",
      "localization": [
        "2jlv6efy9s3f5l9",
        "2ihfygz9uk8ac4d"
      ]
    }
  ]
}

Can't create new user with OAuth (404 from PB)

I want to create a new user using OAuth from the client

final userData = await pb.collection('users').authWithOAuth2('google', (url) async {
      await launchUrl(url, mode: LaunchMode.externalApplication);
});

The window opens in a new browser, I sign into Google, I'm redirected to a page that shows:

{"code":404,"message":"Not Found.","data":{}}

Then nothing happens. I tried different Google accounts. Using latest version of the pocketbase sdk and url_launcher. No existing user in pocketbase with the same email as the google accounts, not even admin

And no rules restricting create access to users collection

Google is also enabled in my list of OAuth providers with the correct client id and secret

AuthStore JWT not invalidating

Hello

I use the dart sdk to authenticate the user + Hive in order to store the RecordModel and JWT Token in the local storage for persistent authentication.

On app start, I run a checkData() function that loads the RecordModel and token from the Hive box and uses authStore.save(token, model) to store the data in the pocketbase authstore.

After that however after calling authStore.isValid it returns true even if I invalidate all tokens from the admin portal under token options and press save.

See called function below:

    checkData() async {
    Hive.registerAdapter(PocketRecordModelAdapter());
    var recordbox = await Hive.openBox("record2");
    PocketRecordModel? prm = Hive.box("record2").get("record2");

    if (prm == null) {
      print("PRM IS null, this is the first time launching the app or user never logged in.");
      return;
    }

    print(prm.getData()); // When succesfull, this returns the RecordModel data

    //Here I create a basic RecordModel from the data stored in Hive
    RecordModel userRecord = RecordModel(
        id: prm.id,
        created: prm.created,
        updated: prm.updated,
        collectionId: prm.collectionId,
        collectionName: prm.collectionName,
        expand: {},
        data: prm.data);
 
    // Save the record in the authstore
    pb.authStore.save(prm.token, userRecord);
    print("model: " + pb.authStore.model.toString());
    print("isvalid?: " + pb.authStore.isValid.toString());
    bool isLoggedIn = pb.authStore.isValid; // THIS IS ALWAYS TRUE EVEN IF INVALIDATED FROM PORTAL

    if (!isLoggedIn) {
      Future.delayed(const Duration(milliseconds: 1000), () => redirect(const Login()));
      return;
    }

    Future.delayed(const Duration(milliseconds: 1000), () => redirect(Dashboard(username: pb.authStore.model.data['username'])));
  }

shouldn't authStore.isValid return false if all tokens have been invalidated from portal?
Is there something I'm missing?

I use pocketbase 0.5.0 as a depedency

Weird create function with body and files in Dart SDK

I am trying to create record with data and files (like example in https://pocketbase.io/docs/files-handling/)

here is my code:

final files = await Future.wait(
  images.map(
    (XFile image) => MultipartFile.fromPath(
      'images',
      image.path,
      filename: 'abc.jpg',
    ),
  ),
);

final body = <String, dynamic>{
  "text": "123",
};

final record = await pb.collection('collection').create(
  files: files,
  body: body,
);

but when I run above code, only files are successfully uploaded to DB and no body data is reflected in DB.
if I comment out files like this:

final record = await pb.collection('collection').create(
  // files: files,
  body: body,
);

then body is successfully uploaded to DB.

why is this happening and how can I solve this?
I can't find any difference between my code and example in https://pocketbase.io/docs/files-handling/

thank you

FormatException when making authenticated requests

Description

"FormatException: Invalid length, must be multiple of four" is thrown when making authenticated requests. There is an open issue with the dart-sdk on this #39510

Steps to reproduce

  1. Running the following code.
import 'package:pocketbase/pocketbase.dart';

void main(List<String> args) async {
  final client = PocketBase('http://localhost:8090');
  const email = 'email';
  const password = 'password';
  final authData = await client.users.authViaEmail(email, password);
  final records = await client.records.getFullList('tasks');
}

Expected result

A list of records

Actual result

Format exception

Unhandled exception:
FormatException: Invalid length, must be multiple of four (at character 75)
eyJleHAiOjE2NjA1OjA3NRIsImlkIjoiUFg2c2oyVlJTcjlRbHpHIiwidHlwZSI6InVzZXIifQ
                                                                          ^

#0      _Base64Decoder.close (dart:convert/base64.dart:639:7)
#1      Base64Decoder.convert (dart:convert/base64.dart:510:13)
#2      Base64Codec.decode (dart:convert/base64.dart:83:47)
#3      base64Decode (dart:convert/base64.dart:52:49)
#4      AuthStore.isValid (package:pocketbase/src/auth_store.dart:41:32)
#5      PocketBase.send (package:pocketbase/src/client.dart:117:60)
#6      _BaseCrudService._getList (package:pocketbase/src/services/base_crud_service.dart:289:19)
#7      _BaseCrudService._getFullList.request (package:pocketbase/src/services/base_crud_service.dart:252:14)    
#8      _BaseCrudService._getFullList.request (package:pocketbase/src/services/base_crud_service.dart:251:28)    
#9      _BaseCrudService._getFullList (package:pocketbase/src/services/base_crud_service.dart:271:12)
#10     SubCrudService.getFullList (package:pocketbase/src/services/base_crud_service.dart:135:12)

Possible solution

Normalize the token sub-string first before decoding it

// pocketbase-0.1.0+4\lib\src\auth_store.dart

...
// Normalize the token sub-string first before decoding
final part = base64.normalize(parts[1]);
final data = jsonDecode(utf8.decode(base64Decode(part))) as Map<String, dynamic>;
...

Additional information

Will submit a PR with the above possible solution.

Environment

OS: Windows
Dart SDK version: 2.17.6 (stable) (Tue Jul 12 12:54:37 2022 +0200) on "windows_x64"

How to close browser with successful oauth using authWithOAuth2?

Using the following:

final userData = await pb .collection('users').authWithOAuth2('google', (url) async {
      await launchUrl(url, mode: LaunchMode.externalApplication); // url_launcher
});

A browser is opened and authentication succeeds. But how can I close the browser once the user is authenticated?

I also tried flutter_custom_tabs but that seems to be no longer maintained and does't have a way to close the tab as far as I can tell

I thought authWithOAuth2 was supposed to close the broswer automatically

Parsing from RecordModel

What's the intended way of parsing the responses from methods like client.record.getList into proper models? I see the RecordModel and it's getters for individual fields, but I would prefer to have proper domain modrls in the app and don't know how to parse them in an efficient way.

Can you provide an example?

Discord OAuth Issue

I am trying to set up oauth with discord. However the code seems to be stuck.
The last printed message to the console is go and the OAuth Flow looks never started and I dont get any exception or message.

import 'package:url_launcher/url_launcher.dart';
import 'package:pocketbase/pocketbase.dart';
....
print("go");
final pb = PocketBase('someurl.fly.dev');
        final authData2 =
            await pb.collection('users').authWithOAuth2('discord', (url) async {
              print(url);
          launchUrl(url);
        });

My Discord OAuth config:
image

My Pocketbase config:
image

Streamline requests' _jsonRequest and _multipartRequest body

When working on a little project I have, I stumbled upon some seemingly random "null" text strings in PocketBase in text fields. I found out that the difference is when a file was uploaded or not. If I send a file with the request, the _multipartRequest uses a custom little function to add all values in the body:

http.MultipartRequest _multipartRequest(
  String method,
  Uri url, {
  Map<String, String> headers = const {},
  Map<String, dynamic> body = const {},
  List<http.MultipartFile> files = const [],
}) {
  final request = http.MultipartRequest(method, url)
    ..files.addAll(files)
    ..headers.addAll(headers);

  body.forEach((key, value) {
    if (value is Iterable) {
      for (var i = 0; i < value.length; i++) {
        request.fields["$key[$i]"] = value.elementAt(i).toString();
      }
    } else {
        request.fields[key] = value.toString();
    }
  });

  return request;
}

Comparing this to when there's no file present in the request:

http.Request _jsonRequest(
  String method,
  Uri url, {
  Map<String, String> headers = const {},
  Map<String, dynamic> body = const {},
}) {
  final request = http.Request(method, url);

  if (body.isNotEmpty) {
    request.body = jsonEncode(body);
  }

  if (headers.isNotEmpty) {
    request.headers.addAll(headers);
  }

  if (!headers.containsKey("Content-Type")) {
    request.headers["Content-Type"] = "application/json";
  }

  return request;
}

The key point to not is in the _jsonRequest function we just use jsonEncode to encode the body. This makes null values actually be null, instead of the _multipartRequest where it's stringyfied. My guess is that there's other values like this, like numbers and booleans that's affected too, but I'm not sure if PocketBase cares about those. I just noticed it with specifically null-values, in file-uploads. My simple fix for the time being is the following code:

  http.MultipartRequest _multipartRequest(
    String method,
    Uri url, {
    Map<String, String> headers = const {},
    Map<String, dynamic> body = const {},
    List<http.MultipartFile> files = const [],
  }) {
    final request = http.MultipartRequest(method, url)
      ..files.addAll(files)
      ..headers.addAll(headers);

    body.forEach((key, value) {
      if (value is Iterable) {
        for (var i = 0; i < value.length; i++) {
          request.fields["$key[$i]"] = value.elementAt(i).toString();
        }
      } else {
        if (value == null) request.fields[key] = null;
        else request.fields[key] = value.toString();
      }
    });

    return request;
  }

I just added a simple if-statement to specifically say the key is null, instead of using toString(). I don't really think the value is even necessary, but the jsonEncode function still has all null-values, so I also let it stay to streamline.

Unable to Login

I'm unable to log in to pocketbase with the users' method.
But I'm able to log in with the admins' method.

When trying to login, I'm getting this error

{
  "errorDetails": "sql: no rows in result set",
  "errorMessage": "Failed to authenticate."
}

Any Idea?

Add a RecordModel.getMapValue() method

I have run into a headache while trying to work with a database. Some of the fields store json data, which I would like to access directly. The methods getStringValue() etc are super useful for pulling other fields, but getting the value out of a field that holds json is much more involved. It would be great if there was a method for the RecordModel class to directly access these fields, returning a Map<String, dynamic>. Perhaps this isn't technically feasible, but I thought I would suggest it just in case.

I cant create new collections and edit fields

Hello everyone.
First I want to thank everyone who has done this work. is awesome!.

Now the problem is that after migrating to version 8 I can't create new collections and I can't edit the fields of the ones I already had created.

I receive the message:
image
image

thanks so much.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.