Flutter Notion数据库交互插件notion_db_sdk的使用

Flutter Notion数据库交互插件notion_db_sdk的使用

notion_db_sdk 是一个类型安全且结构化的方式来与 Notion API 进行交互。该客户端处理来自 Notion 数据库的结构化数据,专注于属性管理,同时忽略嵌入样式、页面块和其他非数据库元素。

该包遵循的一条规则:

只以类型安全的方式处理原始的、结构化的数据,并忽略所有诸如样式、格式、页面块等“花哨”的东西。

快速开始

import 'package:notion_db_sdk/notion_db_sdk.dart';

void main() async {
  // 初始化 Notion 客户端
  final client = NotionClient(
    options: NotionOptions(
      secret: 'your_notion_api_secret',
      version: 'your_notion_api_version',
    ),
  );

  // 查询数据库
  final result = await client.query('database_id');

  result.fold(
    onSuccess: (paginatedResponse) {
      // 处理成功响应
      final pages = paginatedResponse.results;
      for (final page in pages) {
        // 访问页面属性
        print(page.properties['Title']?.value);
      }
    },
    onFailure: (error) {
      // 处理错误
      print('Error: $error');
    },
  );
}

理解 Notion 属性

在 Notion 中,属性定义了存储在数据库中的信息的结构和类型。此 SDK 模仿了 Notion 的属性结构,使其读取和写入数据变得简单,同时忽略了样式信息和复杂的嵌套结构。

该包的主要优点在于其在读取和写入 Notion 数据库时的简洁性。它抽象掉了直接 API 调用通常需要的复杂 JSON 结构。

SDK 与直接 API 调用对比

读取属性

使用 API 读取值涉及处理以下 JSON:

{
  "Description": {
    "id": "a%7BUf",
    "type": "rich_text",
    "rich_text": [
      {
        "type": "text",
        "text": {
          "content": "A dark sky",
          "link": null
        },
        "annotations": {
          "bold": false,
          "italic": false,
          "strikethrough": false,
          "underline": false,
          "code": false,
          "color": "default"
        },
        "plain_text": "A dark sky",
        "href": null
      }
    ]
  },
  "Price": {
    "id": "uCG%3A",
    "type": "number",
    "number": 42
  },
  "Due Date": {
    "id": "%5E%7Cny",
    "type": "date",
    "date": {
      "start": "2023-02-23",
      "end": null,
      "time_zone": null
    }
  }
}

使用 SDK,可以轻松访问这些值:

page.properties['Description'].value // "A dark sky"
page.properties['Price'].value // 42
page.properties['Due Date'].value // DateTime(2023, 2, 23)

写入属性

使用 API 创建具有标题、数字和日期属性的新页面:

{
  "parent": { "database_id": "your_database_id" },
  "properties": {
    "Name": {
      "title": [
        {
          "text": {
            "content": "New Page Title"
          }
        }
      ]
    },
    "Price": {
      "number": 42
    },
    "Due Date": {
      "date": {
        "start": "2023-05-20"
      }
    }
  }
}

使用 SDK,同样的操作可以简化为:

final properties = [
  TextProperty(
    name: 'Name',
    valueDetails: Value(value: 'New Page Title'),
    isTitle: true,
  ),
  Number(
    name: 'Price',
    valueDetails: Value(value: 42),
  ),
  Date(
    name: 'Due Date',
    valueDetails: Value(value: DateTime(2023, 5, 20)),
  ),
];

await client.createPage(
  databaseId: 'your_database_id',
  properties: properties,
);

使用

初始化客户端

要使用 Notion DB SDK,首先初始化 NotionClient 并传入你的 API 凭证:

final client = NotionClient(
  options: NotionOptions(
    secret: 'your_notion_api_secret',
    version: 'your_notion_api_version',
  ),
);

查询数据库

要查询 Notion 数据库:

final result = await client.query('your_database_id');

result.fold(
  onSuccess: (paginatedResponse) {
    final pages = paginatedResponse.results;
    // 处理成功响应
  },
  onFailure: (error) {
    // 处理错误
    print('Error: $error');
  },
);

创建新页面

要在 Notion 数据库中创建新页面:

final properties = [
  TextProperty(
    name: 'Name',
    valueDetails: Value(value: 'New Page Title'),
    isTitle: true,
  ),
  Number(
    name: 'Price',
    valueDetails: Value(value: 42),
  ),
  Date(
    name: 'Due Date',
    valueDetails: Value(value: DateTime(2023, 5, 20)),
  ),
];

final result = await client.createPage(
  databaseId: 'your_database_id',
  properties: properties,
);

result.fold(
  onSuccess: (_) {
    print('Page created successfully');
  },
  onFailure: (error) {
    print('Error creating page: $error');
  },
);

更新页面

要更新 Notion 数据库中的现有页面:

final properties = [
  TextProperty(
    name: 'Name',
    valueDetails: Value(value: 'Updated Task Name'),
  ),
  Number(
    name: 'Priority',
    valueDetails: Value(value: 2),
  ),
];

final result = await client.updatePage(
  pageId: 'page_id',
  properties: properties,
);

result.fold(
  onSuccess: (_) {
    print('Page updated successfully');
  },
  onFailure: (error) {
    print('Error updating page: $error');
  },
);

过滤

单个过滤器

要使用单个过滤器,创建适当过滤器类的实例并将其传递给 query 方法:

final filter = TextFilter('Title', contains: 'Foo');

final result = await client.query(
  'database_id',
  filter: filter,
);

result.fold(
  onSuccess: (paginatedResponse) {
    // 处理过滤结果
  },
  onFailure: (error) {
    // 处理错误
  },
);

过滤器操作符

您可以使用 AndFilterOrFilter 组合多个过滤器:

final filter = AndFilter([
  TextFilter('Title', contains: 'Foo'),
  NumberFilter('Priority', greaterThan: 5),
]);

final result = await client.query(
  'database_id',
  filter: filter,
);

嵌套过滤器

您可以创建复杂的查询,通过嵌套 AND 和 OR 过滤器:

final filter = AndFilter([
  TextFilter('Title', contains: 'Foo'),
  OrFilter([
    NumberFilter('Priority', greaterThan: 8),
    DateFilter('DueDate', before: DateTime.now()),
  ]),
]);

final result = await client.query(
  'database_id',
  filter: filter,
);

排序

您可以使用 SortBuilder 对查询结果进行排序:

final sortBuilder = SortBuilder()
  ..addPropertySort('Name')
  ..addTimestampSort('created_time', direction: SortDirection.descending);

final sorts = sortBuilder.build();

final result = await client.query(
  'database_id',
  sorts: sorts,
);

分页

query 方法支持分页:

final paginationParams = CursorPaginationStrategyParams(
  limit: 50,
  cursor: 'next_cursor_from_previous_query',
);

final result = await client.query(
  'database_id',
  paginationParams: paginationParams,
);

result.fold(
  onSuccess: (paginatedResponse) {
    final pages = paginatedResponse.results;
    final nextCursor = paginatedResponse.paginationParams.cursor;
    // 如果有更多结果,请使用 nextCursor 进行下一次查询
  },
  onFailure: (error) {
    // 处理错误
  },
);

强制获取相关页面

query 方法中的 forceFetchRelationPages 选项允许您自动解析并获取相关页面的属性。这在需要立即访问相关页面的属性而无需单独的 API 调用时非常有用。

final result = await useCase.query('database_id', forceFetchRelationPages: true);

result.fold(
  onSuccess: (properties) {
    properties['related_pages'].first.value; // 访问第一个相关页面的值
  },
  onFailure: (error) => print('Error: $error'),
);

它提供了在一个查询中获取所有相关页面并一次性使用它们的便利。如果有许多相关页面,建议将 [forceFetchRelationPages] 设置为 false,因为这会导致大量 API 调用。在这种情况下,建议按需手动解析相关页面。

final result = await useCase.query('database_id');

final properties = result.valueOrNull ?? [];
final relation = properties['related_pages'].first as RelationProperty;
await relation.valueDetails?.value.first.resolve(useCase); // 解析

relation.valueDetails?.value.first.value; // 访问第一个相关页面的值

更多关于Flutter Notion数据库交互插件notion_db_sdk的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Notion数据库交互插件notion_db_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用notion_db_sdk插件与Notion数据库进行交互的代码示例。这个示例展示了如何获取Notion数据库中的数据。

首先,确保你已经在pubspec.yaml文件中添加了notion_db_sdk依赖:

dependencies:
  flutter:
    sdk: flutter
  notion_db_sdk: ^最新版本号 # 替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用notion_db_sdk

  1. 导入包
import 'package:flutter/material.dart';
import 'package:notion_db_sdk/notion_db_sdk.dart';
  1. 配置Notion API

在使用notion_db_sdk之前,你需要获取Notion的Integration Token和数据库ID。这些信息可以从Notion的Integration页面获取。

  1. 创建Notion客户端
final String token = '你的Notion Integration Token';
final String databaseId = '你的Notion 数据库 ID';

NotionClient client = NotionClient(token: token);
  1. 获取数据库中的数据
void fetchNotionData() async {
  try {
    DatabaseQuery query = DatabaseQuery(databaseId: databaseId);
    DatabaseResponse response = await client.getDatabase(query);

    // 打印获取到的数据
    print(response.results);

    // 你可以在这里更新UI,例如使用setState来更新ListView等
  } catch (e) {
    print('Error fetching Notion data: $e');
  }
}
  1. 在Flutter Widget中调用
void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    fetchNotionData(); // 在应用启动时获取数据
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Notion Database Interaction'),
        ),
        body: Center(
          child: Text('Fetching data from Notion...'), // 这里可以替换为实际显示数据的Widget
        ),
      ),
    );
  }
}

注意:

  • 在实际使用中,你可能需要在UI中显示获取到的数据,这可以通过将数据保存在State中,并在build方法中使用这些数据来更新UI。
  • 错误处理也是非常重要的,确保你的应用能够优雅地处理网络错误或数据解析错误。

这个示例提供了一个基本的框架,你可以根据具体需求进行扩展和修改,例如添加分页、过滤、排序等功能。希望这对你有所帮助!

回到顶部