Skip to content

Commit

Permalink
Merge pull request #10 from jutuon/major-update
Browse files Browse the repository at this point in the history
Major update
  • Loading branch information
rj76 authored May 27, 2024
2 parents cd7323c + 32471f2 commit bbbd91c
Show file tree
Hide file tree
Showing 31 changed files with 792 additions and 1,116 deletions.
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# follow the instructions in the [Firebase Documentation](https://firebase.google.com/docs/cloud-messaging/auth-server#provide-credentials-manually) to create a service account. after you create a service account, and download the json file then change the value of `GOOGLE_APPLICATION_CREDENTIALS` to the path of the json file you downloaded.
# Follow the instructions in the
# [Firebase Documentation](https://firebase.google.com/docs/cloud-messaging/auth-server#provide-credentials-manually)
# to download service account key JSON file. After downloading
# the JSON file then change the value of `GOOGLE_APPLICATION_CREDENTIALS` to
# the path of the JSON file you downloaded.
GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/firebase/file.json"
6 changes: 0 additions & 6 deletions .envrc

This file was deleted.

18 changes: 2 additions & 16 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
runs-on: ${{ matrix.os }}

env:
RUSTFLAGS: "-Dwarnings -Cinstrument-coverage -Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
RUSTFLAGS: "-Dwarnings -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
CARGO_INCREMENTAL: "0"
RUSTDOCFLAGS: "-Cpanic=abort"
RUSTC_BOOTSTRAP: "1"
Expand All @@ -61,7 +61,6 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{matrix.rust}}
components: llvm-tools-preview

- uses: actions/cache@v2
with:
Expand All @@ -72,18 +71,5 @@ jobs:
- name: Build
run: cargo build

- name: Install grcov
run: cargo install grcov

- name: Run tests
run: LLVM_PROFILE_FILE="fcm-rust-%p-%m.profraw" cargo test

- name: Collect results
run: grcov . -s . --binary-path ./target/debug/ -t lcov --branch --ignore-not-existing -o ./tests.lcov

- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v2.2.3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
file: ./tests.lcov

run: cargo test
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Cargo.lock

.DS_Store

.direnv
.idea/

# local env files
# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
# Local env files
# Do not commit any .env files to git, except for the .env.example file.
# https://create.t3.gg/en/usage/env-variables#using-environment-variables
.env
.env*.local
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ edition = "2018"

[features]
default = ["native-tls"]

native-tls = ["reqwest/native-tls"]
rustls = ["reqwest/rustls-tls"]
vendored-tls = ["reqwest/native-tls-vendored"]

[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
erased-serde = "0.4.1"
reqwest = {version = "0.11.0", features = ["json"], default-features=false}
tokio = { version = "1", features = ["fs"] }
reqwest = { version = "0.11", features = ["json"], default-features = false }
chrono = "0.4"
log = "0.4"
gauth = "0.7.0"
dotenv = "0.15.0"
thiserror = "1"
dotenvy = "0.15"
yup-oauth2 = "9"

[dev-dependencies]
argparse = "0.2.1"
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
pretty_env_logger = "0.5.0"
clap = { version = "4.5", features = ["cargo", "derive"] }
79 changes: 46 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# fcm-rust
[![Cargo tests](https://github.com/rj76/fcm-rust/actions/workflows/test.yml/badge.svg)](https://github.com/rj76/fcm-rust/actions/workflows/test.yml)
[![Coverage Status](https://coveralls.io/repos/github/rj76/fcm-rust/badge.svg)](https://coveralls.io/github/rj76/fcm-rust)

[//]: # ([![Crates.io Version](https://img.shields.io/crates/v/fcm.svg?style=flat-square))
[//]: # ([![Crates.io Downloads](https://img.shields.io/crates/dv/fcm.svg?style=flat-square))
Expand All @@ -23,7 +22,8 @@ Add the following to your `Cargo.toml` file:
fcm = { git = "https://github.com/rj76/fcm-rust.git" }
```

Then, you need to add the credentials described in the [Credentials](#credentials) to a `.env` file at the root of your project.
Optionally, add the credentials described in the [Credentials](#credentials)
to a `.env` file at the root of your project.

## Usage

Expand All @@ -38,58 +38,71 @@ use fcm;
### Create a client instance

```rust
let client = fcm::Client::new();
let client = fcm::FcmClient::builder()
// Comment to use GOOGLE_APPLICATION_CREDENTIALS environment
// variable. The variable can also be defined in .env file.
.service_account_key_json_path("service_account_key.json")
.build()
.await
.unwrap();
```

### Construct a message

```rust
let message = fcm::Message {
data: None,
use fcm::message::{Message, Notification, Target};

// Replace "device_token" with the actual device token
let device_token = "device_token".to_string();
let message = Message {
data: Some(json!({
"message": "Howdy!",
})),
notification: Some(Notification {
title: Some("I'm high".to_string()),
title: Some("Hello".to_string()),
body: Some(format!("it's {}", chrono::Utc::now())),
..Default::default()
image: None,
}),
target: Target::Token(device_token),
fcm_options: Some(FcmOptions {
analytics_label: "analytics_label".to_string(),
}),
android: Some(AndroidConfig {
priority: Some(fcm::AndroidMessagePriority::High),
notification: Some(AndroidNotification {
title: Some("I'm Android high".to_string()),
body: Some(format!("Hi Android, it's {}", chrono::Utc::now())),
..Default::default()
}),
..Default::default()
}),
apns: Some(ApnsConfig { ..Default::default() }),
webpush: Some(WebpushConfig { ..Default::default() }),
}
android: None,
webpush: None,
apns: None,
fcm_options: None,
};
```

### Send the message

```rust
let response = client.send(message).await?;
let response = client.send(message).await.unwrap();
```

# Credentials

This library expects the Google credentials JSON location to be
defined as `GOOGLE_APPLICATION_CREDENTIALS` in the `.env` file.
Please follow the instructions in the [Firebase Documentation](https://firebase.google.com/docs/cloud-messaging/auth-server#provide-credentials-manually) to create a service account.

## Examples

For a complete usage example, you may check out the [`simple_sender`](examples/simple_sender.rs) example.
If client is not configured with service account key JSON file path
then this library expects the Google credentials JSON location to be
defined in `GOOGLE_APPLICATION_CREDENTIALS` environment variable.
The variable definition can also be located in the `.env` file.

To run the example, first of all clone the [`.env.example`](.env.example) file to `.env` and fill in the required values.
Please follow the instructions in the
[Firebase Documentation](https://firebase.google.com/docs/cloud-messaging/auth-server#provide-credentials-manually)
to create a service account key JSON file.

You can find info about the required credentials in the [Credentials](#credentials) section.
## Examples

Then run the example with `cargo run --example simple_sender -- -t <device_token>`
For a complete usage example, you may check out the
[`simple_sender`](examples/simple_sender.rs) example.

The example can be run with
```
cargo run --example simple_sender -- -t <device_token> -k <service_account_key_path>
```

If `GOOGLE_APPLICATION_CREDENTIALS` environment variable is defined in current
environment or in `.env` file, then the example can be run with
```
cargo run --example simple_sender -- -t <device_token>
```

To define the environment variable using `.env` file copy the [`.env.example`](.env.example)
file to `.env` and fill in the required values.
77 changes: 37 additions & 40 deletions examples/simple_sender.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,54 @@
// cargo run --example simple_sender -- -t <device_token>
// cargo run --example simple_sender -- --help

use argparse::{ArgumentParser, Store};
use std::path::PathBuf;

use clap::Parser;
use fcm::{
AndroidConfig, AndroidNotification, ApnsConfig, Client, FcmOptions, Message, Notification, Target, WebpushConfig,
message::{Message, Notification, Target},
FcmClient,
};
use serde_json::json;

#[derive(Parser, Debug)]
struct CliArgs {
#[arg(short = 't', long)]
device_token: String,
/// Set path to the service account key JSON file. Default is to use
/// path from the `GOOGLE_APPLICATION_CREDENTIALS` environment variable
/// (which can be also located in `.env` file).
#[arg(short = 'k', long, value_name = "FILE")]
service_account_key_path: Option<PathBuf>,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
pretty_env_logger::init();

let mut device_token = String::new();

{
let mut ap = ArgumentParser::new();
ap.set_description("A simple FCM notification sender");
ap.refer(&mut device_token)
.add_option(&["-t", "--device_token"], Store, "Device token");
ap.parse_args_or_exit();
}

let client = Client::new();
let args = CliArgs::parse();
let builder = FcmClient::builder();
let builder = if let Some(path) = args.service_account_key_path {
builder.service_account_key_json_path(path)
} else {
builder
};

let data = json!({
"key": "value",
});
let client = builder.build().await.unwrap();

let builder = Message {
data: Some(data),
let message = Message {
data: Some(json!({
"key": "value",
})),
notification: Some(Notification {
title: Some("I'm high".to_string()),
body: Some(format!("it's {}", chrono::Utc::now())),
..Default::default()
}),
target: Target::Token(device_token),
fcm_options: Some(FcmOptions {
analytics_label: "analytics_label".to_string(),
}),
android: Some(AndroidConfig {
priority: Some(fcm::AndroidMessagePriority::High),
notification: Some(AndroidNotification {
title: Some("I'm Android high".to_string()),
body: Some(format!("Hi Android, it's {}", chrono::Utc::now())),
..Default::default()
}),
title: Some("Title".to_string()),
..Default::default()
}),
apns: Some(ApnsConfig { ..Default::default() }),
webpush: Some(WebpushConfig { ..Default::default() }),
target: Target::Token(args.device_token),
fcm_options: None,
android: None,
apns: None,
webpush: None,
};

let response = client.send(builder).await?;
println!("Sent: {:?}", response);
let response = client.send(message).await?;
println!("Response: {:#?}", response);

Ok(())
}
80 changes: 0 additions & 80 deletions flake.lock

This file was deleted.

Loading

0 comments on commit bbbd91c

Please sign in to comment.