Closed simplesthing closed 4 years ago
import "react-native-gesture-handler";
import React from "react";
import { Alert } from "react-native";
import AnimatedSplash from "react-native-animated-splash-screen";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import * as Font from "expo-font";
import { Ionicons } from "@expo/vector-icons";
import { AccountProvider } from "./contexts/account";
import Login from "./components/Login/Login";
import MainWindow from "./components/MainWindow";
import Registration from "./components/Login/Registration";
import Constants from "expo-constants";
import RNIap, {
InAppPurchase,
PurchaseError,
acknowledgePurchaseAndroid,
consumePurchaseAndroid,
finishTransaction,
finishTransactionIOS,
purchaseErrorListener,
purchaseUpdatedListener,
} from "react-native-iap";
import { NativeModules } from 'react-native';
const { RNIapModule } = NativeModules;
function hasIAP() {
return !!NativeModules.RNIapModule;
}
const Stack = createStackNavigator();
const expoManaged = () => {
return Constants.appOwnership === "expo";
};
const LoginStack = () => (
<Stack.Navigator initialRouteName="Log in">
<Stack.Screen
name="Log in"
component={Login}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Register"
component={Registration}
options={{ headerTitleAlign: "center" }}
/>
</Stack.Navigator>
);
let purchaseUpdateSubscription;
let purchaseErrorSubscription;
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isReady: false,
user: null,
productList: null,
logs: [],
};
}
async componentDidMount() {
let log = this.state.logs;
log.push('appOwnership: ' + Constants.appOwnership);
log.push('hasIAP() ' + hasIAP());
log.push(JSON.stringify(NativeModules));
await Font.loadAsync({
Roboto: require("native-base/Fonts/Roboto.ttf"),
Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
...Ionicons.font,
});
this.setState({ isReady: true });
if (!expoManaged()) {
try {
const connection = await RNIap.initConnection();
// const consume = await RNIap.consumeAllItemsAndroid(); <- this fails, e.refreshItems is null
log.push("connection: ", connection);
} catch (err) {
log.push("connection error: " + err.code, err.message);
}
log.push("setup purchase listener");
purchaseUpdateSubscription = purchaseUpdatedListener(
async (InAppPurchase) => {
const receipt = purchase.transactionReceipt;
if (receipt) {
try {
const ackResult = await finishTransaction(purchase);
} catch (ackErr) {
log.push("ackErr: ", ackErr);
}
}
}
);
log.push("setup pucrahse error listener");
purchaseErrorSubscription = purchaseErrorListener(
(error: PurchaseError) => {
console.log("purchaseErrorListener", error);
Alert.alert("purchase error", JSON.stringify(error));
}
);
}
this.setState({ logs: log });
}
componentWillUnmount() {
if (purchaseUpdateSubscription) {
purchaseUpdateSubscription.remove();
purchaseUpdateSubscription = null;
}
if (purchaseErrorSubscription) {
purchaseErrorSubscription.remove();
purchaseErrorSubscription = null;
}
RNIap.endConnection();
}
getStoreProducts = async () => {
const itemSkus = Platform.select({
ios: [],
android: [
"test_ticket",
"android.test.purchased",
"android.test.canceled",
"android.test.refunded",
"android.test.item_unavailable",
],
});
let log = this.state.logs;
log.push("try getProducts" + JSON.stringify(itemSkus));
try {
const products = await RNIap.getProducts(itemSkus);
log.push("Products: ", JSON.stringify(products));
this.setState({ productList: products, logs: log });
} catch (err) {
log.push("Products error: " + err.code, err.message);
this.setState({ logs: log });
}
};
requestPurchase = async (sku) => {
let log = this.state.logs;
log.push('try request a purchase with sku: ' + sku);
if(!expoManaged()) {
try {
RNIap.requestPurchase(sku);
} catch (err) {
log.push("request a purchase error: " + err.code, err.message);
}
}
this.setState({ logs: log });
};
onLogin = () => {
this.setState({ user: "username" });
};
render() {
const accountContext = {
user: this.state.user,
onLogin: this.onLogin,
productList: this.state.productList,
logs: this.state.logs,
getStoreProducts: this.getStoreProducts,
requestPurchase: this.requestPurchase,
};
return (
<AnimatedSplash
isLoaded={this.state.isReady}
logoImage={require("./assets/sansar-logo-only.png")}
backgroundColor={"#141414"}
logoHeight={150}
logoWidth={150}
>
<AccountProvider value={accountContext}>
<NavigationContainer>
<Stack.Navigator headerMode="none">
{this.state.user ? (
<Stack.Screen name="Sansar" component={MainWindow} />
) : (
<Stack.Screen name="Auth" component={LoginStack} />
)}
</Stack.Navigator>
</NavigationContainer>
</AccountProvider>
</AnimatedSplash>
);
}
}
Ended up using expo-iap library instead closing
Version of react-native-iap
4.4.9
Version of react-native
0.61.5
Platforms you faced the error (IOS or Android or both?)
Android
Expected behavior
React NativeModeuls shows RNIAP in list of modules
Actual behavior
RNIAp not found
Tested environment (Emulator? Real Device?)
Emulator and Real Device
Steps to reproduce the behavior
Using expo framework, ejected workflow, running both locally with
expo start
as well as on a packaged and distributed APK from google play store, both show no RNAIP module found.